Skip to content

Commit e3d1b32

Browse files
committed
goto-instrument --unwind: unwinding assertions do not disable unwinding assumptions
In keeping with CBMC's behaviour, generate unwinding assumptions even when unwinding assertions are generated for (failing) assertions are not considered fatal in GOTO programs. Unwinding assumptions should only be skipped when partial loops are requested.
1 parent 60d3466 commit e3d1b32

File tree

5 files changed

+27
-13
lines changed

5 files changed

+27
-13
lines changed

regression/goto-instrument/unwind-assert2/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ int main()
33
{
44
int i;
55
for(i = 0; i < 10; i++) {}
6+
__CPROVER_assert(0, "fails when fully unwinding the loop");
67
}

regression/goto-instrument/unwind-assert2/test.desc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
CORE
22
main.c
33
--unwind 9 --unwinding-assertions
4+
^\[main.assertion.1\] line 6 fails when fully unwinding the loop: SUCCESS$
5+
^\*\* 1 of 2 failed
46
^EXIT=10$
57
^SIGNAL=0$
68
^VERIFICATION FAILED$

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ int goto_instrument_parse_optionst::doit()
194194

195195
if(unwinding_assertions)
196196
{
197-
unwind_strategy=goto_unwindt::unwind_strategyt::ASSERT;
197+
unwind_strategy = goto_unwindt::unwind_strategyt::ASSERT_ASSUME;
198198
}
199199
else if(partial_loops)
200200
{

src/goto-instrument/unwind.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ void goto_unwindt::unwind(
128128
}
129129
else
130130
{
131+
PRECONDITION(
132+
unwind_strategy == unwind_strategyt::ASSERT_ASSUME ||
133+
unwind_strategy == unwind_strategyt::ASSUME);
134+
131135
goto_programt::const_targett t=loop_exit;
132136
t--;
133137
assert(t->is_backwards_goto());
@@ -144,22 +148,23 @@ void goto_unwindt::unwind(
144148
exit_cond = loop_head->get_condition();
145149
}
146150

147-
goto_programt::targett new_t;
148-
149-
if(unwind_strategy==unwind_strategyt::ASSERT)
151+
if(unwind_strategy == unwind_strategyt::ASSERT_ASSUME)
150152
{
151-
new_t = rest_program.add(goto_programt::make_assertion(exit_cond));
153+
goto_programt::targett assertion = rest_program.add(
154+
goto_programt::make_assertion(exit_cond, loop_head->source_location()));
155+
unwind_log.insert(assertion, loop_head->location_number);
152156
}
153-
else if(unwind_strategy==unwind_strategyt::ASSUME)
157+
158+
if(
159+
unwind_strategy == unwind_strategyt::ASSUME ||
160+
unwind_strategy == unwind_strategyt::ASSERT_ASSUME)
154161
{
155-
new_t = rest_program.add(goto_programt::make_assumption(exit_cond));
162+
goto_programt::targett assumption =
163+
rest_program.add(goto_programt::make_assumption(
164+
exit_cond, loop_head->source_location()));
165+
unwind_log.insert(assumption, loop_head->location_number);
156166
}
157-
else
158-
UNREACHABLE;
159167

160-
new_t->source_location_nonconst() = loop_head->source_location();
161-
new_t->location_number=loop_head->location_number;
162-
unwind_log.insert(new_t, loop_head->location_number);
163168
}
164169

165170
assert(!rest_program.empty());

src/goto-instrument/unwind.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ class unwindsett;
2121
class goto_unwindt
2222
{
2323
public:
24-
enum class unwind_strategyt { CONTINUE, PARTIAL, ASSERT, ASSUME };
24+
enum class unwind_strategyt
25+
{
26+
CONTINUE,
27+
PARTIAL,
28+
ASSERT_ASSUME,
29+
ASSUME
30+
};
2531

2632
// unwind loop
2733

0 commit comments

Comments
 (0)