Skip to content

Commit abd36cf

Browse files
committed
instrument loop head for inclusion checks as well
Previously, only loop body was being instrumented for write set inclusion checks. This could miss checking writes performed by the loop guard, if it has side effects. In this PR, we also instrument the loop guard with inclusion checks.
1 parent 911db55 commit abd36cf

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

src/goto-instrument/contracts/contracts.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ void code_contractst::check_apply_loop_contracts(
189189
insert_before_swap_and_advance(
190190
goto_function.body, loop_head, snapshot_instructions);
191191
};
192+
193+
// Perform write set instrumentation on the entire loop.
194+
check_frame_conditions(
195+
function_name, goto_function.body, loop_head, loop_end, loop_assigns);
192196
}
193197

194198
havoc_assigns_targetst havoc_gen(modifies, ns);
@@ -251,7 +255,10 @@ void code_contractst::check_apply_loop_contracts(
251255

252256
// Assume invariant & decl the variant temporaries (just before loop guard).
253257
// Use insert_before_swap to preserve jumps to loop head.
254-
insert_before_swap_and_advance(goto_function.body, loop_head, generated_code);
258+
insert_before_swap_and_advance(
259+
goto_function.body,
260+
loop_head,
261+
add_pragma_disable_assigns_check(generated_code));
255262

256263
// Forward the loop_head iterator until the start of the body.
257264
// This is necessary because complex C loop_head conditions could be
@@ -270,13 +277,6 @@ void code_contractst::check_apply_loop_contracts(
270277
auto loop_body = loop_head;
271278
loop_head--;
272279

273-
// Perform write set instrumentation before adding anything else to loop body.
274-
if(assigns.is_not_nil())
275-
{
276-
check_frame_conditions(
277-
function_name, goto_function.body, loop_body, loop_end, loop_assigns);
278-
}
279-
280280
// Generate: assignments to store the multidimensional decreases clause's
281281
// value just before the loop body (but just after the loop guard)
282282
if(!decreases_clause.is_nil())
@@ -290,7 +290,8 @@ void code_contractst::check_apply_loop_contracts(
290290
converter.goto_convert(old_decreases_assignment, generated_code, mode);
291291
}
292292

293-
goto_function.body.destructive_insert(loop_body, generated_code);
293+
goto_function.body.destructive_insert(
294+
loop_body, add_pragma_disable_assigns_check(generated_code));
294295
}
295296

296297
// Generate: assert(invariant) just after the loop exits
@@ -340,7 +341,10 @@ void code_contractst::check_apply_loop_contracts(
340341
}
341342
}
342343

343-
insert_before_swap_and_advance(goto_function.body, loop_end, generated_code);
344+
insert_before_swap_and_advance(
345+
goto_function.body,
346+
loop_end,
347+
add_pragma_disable_assigns_check(generated_code));
344348

345349
// change the back edge into assume(false) or assume(guard)
346350
loop_end->turn_into_assume();

0 commit comments

Comments
 (0)