Skip to content

Commit 8330dd3

Browse files
committed
Loop counter resetting must not result in unlimited unwinding
Loops with multiple entry points previously resulted in unlimited unwinding as loop counters were wrongly being reset via edges leaving one of the loops (and entering the other).
1 parent 818fdf2 commit 8330dd3

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
int main()
2+
{
3+
int x;
4+
int y;
5+
6+
do
7+
{
8+
y = 10;
9+
goto label;
10+
x = 1; // dead code, makes sure the above goto is not removed
11+
label:
12+
_Bool nondet;
13+
if(nondet)
14+
__CPROVER_assert(y != 10, "violated via first loop");
15+
else
16+
__CPROVER_assert(y != 20, "violated via second loop");
17+
18+
if(x % 2)
19+
break; // this statement must not cause the loop counter to be reset
20+
} while(1);
21+
22+
y = 20;
23+
goto label;
24+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--unwind 2
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
^\** 2 of 2 failed
8+
--
9+
--
10+
Loop unwinding must terminate despite the existence of multiple loop entry
11+
points.

src/goto-symex/symex_main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void symex_transition(
9797
for(const auto &i_e : instruction.incoming_edges)
9898
{
9999
if(
100-
i_e->is_goto() && i_e->is_backwards_goto() &&
100+
i_e->is_backwards_goto() && i_e->get_target() == to &&
101101
(!is_backwards_goto ||
102102
state.source.pc->location_number > i_e->location_number))
103103
{

0 commit comments

Comments
 (0)