File tree Expand file tree Collapse file tree 5 files changed +85
-4
lines changed
invar_dynamic_struct_member Expand file tree Collapse file tree 5 files changed +85
-4
lines changed Original file line number Diff line number Diff line change 1+ typedef struct test
2+ {
3+ int x ;
4+ } test ;
5+
6+ void main ()
7+ {
8+ struct test * t = malloc (sizeof (test ));
9+ t -> x = 0 ;
10+
11+ unsigned n ;
12+ for (unsigned i = 0 ; i < n ; ++ i )
13+ __CPROVER_loop_invariant (i <= n )
14+ {
15+ switch (i % 4 )
16+ {
17+ case 0 :
18+ break ;
19+
20+ case 1 :
21+ case 2 :
22+ t -> x += 1 ;
23+
24+ default :
25+ t -> x += 2 ;
26+ }
27+ }
28+
29+ assert (t -> x == 0 || t -> x == 1 || t -> x == 2 );
30+ }
Original file line number Diff line number Diff line change 1+ CORE
2+ main.c
3+ --enforce-all-contracts
4+ ^EXIT=10$
5+ ^SIGNAL=0$
6+ ^\[main.1\] .* Check loop invariant before entry: SUCCESS$
7+ ^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
8+ ^\[main.assertion.1\] .* assertion .*: FAILURE$
9+ ^VERIFICATION FAILED$
10+ --
11+ --
12+ This test checks that members of typedef'd and dynamically allocated structs
13+ are correctly havoced when enforcing loop invariants.
14+ The assertion is expected to fail when `t->x` is correctly havoced (so would be
15+ set to a nondet value).
16+ However, it `t->x` is not havoced then it stays at value `0` and would satisfy
17+ the assertion when the loop is replaced by a single nondet iteration.
18+
Original file line number Diff line number Diff line change 1+ struct test
2+ {
3+ int x ;
4+ };
5+
6+ void main ()
7+ {
8+ struct test t ;
9+ t .x = 0 ;
10+
11+ unsigned n ;
12+ for (unsigned i = 0 ; i < n ; ++ i )
13+ __CPROVER_loop_invariant (i <= n )
14+ {
15+ t .x += 2 ;
16+ }
17+
18+ assert (t .x == 0 || t .x == 2 );
19+ }
Original file line number Diff line number Diff line change 1+ CORE
2+ main.c
3+ --enforce-all-contracts
4+ ^EXIT=10$
5+ ^SIGNAL=0$
6+ ^\[main.1\] .* Check loop invariant before entry: SUCCESS$
7+ ^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
8+ ^\[main.assertion.1\] .* assertion t.x == 0 || t.x == 2: FAILURE$
9+ ^VERIFICATION FAILED$
10+ --
11+ --
12+ This test checks that members of statically allocated are correctly havoced
13+ when enforcing loop invariants.
14+ The `t.x == 0 || t.x == 2` assertion is expected to fail when `t.x` is correctly
15+ havoced (so would be set to a nondet value).
16+ However, it `t.x` is not havoced then it stays at value `0` and would satisfy
17+ the assertion when the loop is replaced by a single nondet iteration.
Original file line number Diff line number Diff line change @@ -61,17 +61,14 @@ void get_modifies_lhs(
6161 const exprt &lhs,
6262 modifiest &modifies)
6363{
64- if (lhs.id ()== ID_symbol)
64+ if (lhs.id () == ID_symbol || lhs. id () == ID_member )
6565 modifies.insert (lhs);
6666 else if (lhs.id ()==ID_dereference)
6767 {
6868 const auto &pointer = to_dereference_expr (lhs).pointer ();
6969 for (const auto &mod : local_may_alias.get (t, pointer))
7070 modifies.insert (dereference_exprt{mod});
7171 }
72- else if (lhs.id ()==ID_member)
73- {
74- }
7572 else if (lhs.id ()==ID_index)
7673 {
7774 }
You can’t perform that action at this time.
0 commit comments