Skip to content

CONTRACTS: fix do while latch #8420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
// IF g THEN GOTO HEAD
// --------------------------
// IF !g THEN GOTO EXIT
// GOTO HEAD
// IF TRUE GOTO HEAD
// EXIT: SKIP
// ```
if(latch->has_condition() && !latch->condition().is_true())
Expand All @@ -162,24 +162,38 @@
const auto &exit =
goto_program.insert_after(latch, goto_programt::make_skip(loc));

// Insert the loop exit jump `F !g THEN GOTO EXIT`

Check warning on line 165 in src/goto-instrument/contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp

View check run for this annotation

Codecov / codecov/patch

src/goto-instrument/contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp#L165

Added line #L165 was not covered by tests
insert_before_and_update_jumps(
goto_program,
latch,
goto_programt::make_goto(
exit, not_exprt(latch->condition()), latch->source_location()));

// CAUTION: The condition expression needs to be updated in place because
// this is where loop contract clauses are stored as extra ireps.
// Overwriting this expression with a fresh expression will also lose the
// loop contract.
exprt latch_condition = latch->condition();
latch_condition.set(ID_value, ID_true);
*latch = goto_programt::make_goto(head, latch_condition, loc);
}
// Rewrite the latch node `IF g THEN GOTO HEAD`
// into `IF true THEN GOTO HEAD`
// and transplanting contract clauses
exprt new_condition = true_exprt();

// Extract the contract clauses from the existing latch condition,

Check warning on line 177 in src/goto-instrument/contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp

View check run for this annotation

Codecov / codecov/patch

src/goto-instrument/contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp#L177

Added line #L177 was not covered by tests
const exprt &latch_condition = latch->condition();
irept latch_assigns = latch_condition.find(ID_C_spec_assigns);
if(latch_assigns.is_not_nil())
new_condition.add(ID_C_spec_assigns).swap(latch_assigns);

irept latch_loop_invariant =
latch_condition.find(ID_C_spec_loop_invariant);
if(latch_loop_invariant.is_not_nil())
new_condition.add(ID_C_spec_loop_invariant).swap(latch_loop_invariant);

// The latch node is now an unconditional jump.
irept latch_decreases = latch_condition.find(ID_C_spec_decreases);
if(latch_decreases.is_not_nil())
new_condition.add(ID_C_spec_decreases).swap(latch_decreases);

Check warning on line 190 in src/goto-instrument/contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp

View check run for this annotation

Codecov / codecov/patch

src/goto-instrument/contracts/dynamic-frames/dfcc_check_loop_normal_form.cpp#L190

Added line #L190 was not covered by tests

latch->condition_nonconst() = new_condition;
// The latch node is now an unconditional jump with contract clauses
}

// insert a SKIP pre-head node and reroute all incoming edges to that node,
// Insert a SKIP pre-head node and reroute all incoming edges to that node,
// except for edge coming from the latch.
insert_before_and_update_jumps(
goto_program, head, goto_programt::make_skip(head->source_location()));
Expand Down
Loading