Skip to content

Commit bb5ea27

Browse files
Merge pull request #7216 from qinheping/assigns_inference
CONTRACTS: Fix inferring assigns clause with symbols out of scope
2 parents 178df3d + 8115bb9 commit bb5ea27

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <assert.h>
2+
3+
int j;
4+
5+
int lowerbound()
6+
{
7+
return 0;
8+
}
9+
10+
int upperbound()
11+
{
12+
return 10;
13+
}
14+
15+
void incr(int *i)
16+
{
17+
(*i)++;
18+
}
19+
20+
void body_1(int i)
21+
{
22+
j = i;
23+
}
24+
25+
void body_2(int *i)
26+
{
27+
(*i)++;
28+
(*i)--;
29+
}
30+
31+
int body_3(int *i)
32+
{
33+
(*i)++;
34+
if(*i == 4)
35+
return 1;
36+
37+
(*i)--;
38+
return 0;
39+
}
40+
41+
int main()
42+
{
43+
for(int i = lowerbound(); i < upperbound(); incr(&i))
44+
// clang-format off
45+
__CPROVER_loop_invariant(0 <= i && i <= 10)
46+
__CPROVER_loop_invariant(i != 0 ==> j + 1 == i)
47+
// clang-format on
48+
{
49+
body_1(i);
50+
51+
if(body_3(&i))
52+
return 1;
53+
54+
body_2(&i);
55+
}
56+
57+
assert(j == 9);
58+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[body_1.assigns.\d+\] .* Check that j is assignable: SUCCESS$
7+
^\[body_2.assigns.\d+\] .* Check that \*i is assignable: SUCCESS$
8+
^\[body_3.assigns.\d+\] .* Check that \*i is assignable: SUCCESS$
9+
^\[incr.assigns.\d+\] .* Check that \*i is assignable: SUCCESS$
10+
^\[main.\d+\] .* Check loop invariant before entry: SUCCESS$
11+
^\[main.\d+\] .* Check that loop invariant is preserved: SUCCESS$
12+
^\[main.assertion.\d+\] .* assertion j == 9: SUCCESS$
13+
^VERIFICATION SUCCESSFUL$
14+
--
15+
--
16+
This test checks loop locals are correctly removed during assigns inference so
17+
that the assign clause is correctly inferred.

src/goto-instrument/contracts/cfg_info.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Date: June 2022
1919

2020
#include <util/byte_operators.h>
2121
#include <util/expr_cast.h>
22+
#include <util/find_symbols.h>
2223
#include <util/message.h>
2324

2425
#include <goto-programs/goto_model.h>
@@ -172,8 +173,12 @@ class loop_cfg_infot : public cfg_infot
172173
auto it = exprs.begin();
173174
while(it != exprs.end())
174175
{
176+
const std::unordered_set<irep_idt> symbols = find_symbol_identifiers(*it);
177+
175178
if(
176-
it->id() == ID_symbol && is_local(to_symbol_expr(*it).get_identifier()))
179+
std::find_if(symbols.begin(), symbols.end(), [this](const irep_idt &s) {
180+
return is_local(s);
181+
}) != symbols.end())
177182
{
178183
it = exprs.erase(it);
179184
}

0 commit comments

Comments
 (0)