Skip to content

Commit 2499f8a

Browse files
committed
reject contracts on do/while loops for now
Whether the first (unguarded) loop iteration should be executed "before" the base case assertion or not is still under discussion. Loop contracts on do/while loops are rejected until this is resolved.
1 parent b5b8a5a commit 2499f8a

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
int x = 0;
6+
7+
do
8+
{
9+
x++;
10+
} while(x < 10) __CPROVER_loop_invariant(0 <= x && x <= 10);
11+
12+
assert(x == 10);
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
KNOWNBUG
2+
main.c
3+
--apply-loop-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
This test checks that loop contracts work correctly on do/while loops.

src/goto-instrument/contracts/contracts.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,14 @@ void code_contractst::check_apply_loop_contracts(
184184
new_decreases_vars.push_back(new_decreases_var);
185185
}
186186

187-
// non-deterministically skip the loop if it is a do-while loop
188-
if(!loop_head->is_goto())
187+
// TODO: Fix loop contract handling for do/while loops.
188+
if(loop_end->is_goto() && !loop_end->get_condition().is_true())
189189
{
190+
log.error() << "Loop contracts are unsupported on do/while loops: "
191+
<< loop_head->source_location() << messaget::eom;
192+
throw 0;
193+
194+
// non-deterministically skip the loop if it is a do-while loop.
190195
havoc_code.add(goto_programt::make_goto(
191196
loop_end,
192197
side_effect_expr_nondett(bool_typet(), loop_head->source_location())));
@@ -276,11 +281,7 @@ void code_contractst::check_apply_loop_contracts(
276281

277282
// change the back edge into assume(false) or assume(guard)
278283
loop_end->turn_into_assume();
279-
280-
if(loop_head->is_goto())
281-
loop_end->set_condition(false_exprt());
282-
else
283-
loop_end->set_condition(boolean_negate(loop_end->get_condition()));
284+
loop_end->set_condition(boolean_negate(loop_end->get_condition()));
284285
}
285286

286287
void code_contractst::add_quantified_variable(

0 commit comments

Comments
 (0)