Skip to content

Commit 169dc18

Browse files
Merge pull request #6546 from remi-delmas-3000/guarded-assigns-targets
Function contracts: preliminary support for conditional targets in assigns clause checking
2 parents 27b02b3 + 4a10dd4 commit 169dc18

File tree

63 files changed

+1300
-281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1300
-281
lines changed

regression/contracts/assigns_enforce_address_of/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--enforce-contract foo
44
^EXIT=(1|64)$
55
^SIGNAL=0$
6-
^.*error: non-lvalue target in assigns clause$
6+
^.*error: assigns clause target must be an lvalue or __CPROVER_POINTER_OBJECT expression$
77
^CONVERSION ERROR$
88
--
99
--
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <stdbool.h>
2+
3+
bool cond()
4+
{
5+
return true;
6+
}
7+
8+
int foo(int a, int *x, int *y)
9+
// clang-format off
10+
__CPROVER_assigns(a && cond() : *x)
11+
// clang-format on
12+
{
13+
if(a)
14+
{
15+
if(cond())
16+
*x = 0; // must pass
17+
}
18+
else
19+
{
20+
*x = 0; // must fail
21+
}
22+
return 0;
23+
}
24+
25+
int main()
26+
{
27+
bool a;
28+
int x;
29+
int y;
30+
31+
foo(a, &x, &y);
32+
return 0;
33+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
main.c
3+
--enforce-contract foo
4+
^main.c function foo$
5+
^\[foo\.\d+\] line 16 Check that \*x is assignable: SUCCESS$
6+
^\[foo\.\d+\] line 20 Check that \*x is assignable: FAILURE$
7+
^VERIFICATION FAILED$
8+
^EXIT=10$
9+
^SIGNAL=0$
10+
--
11+
--
12+
Checks that function calls are allowed in conditions.
13+
Remark: we allow function calls without further checks for now because they
14+
are mandatory for some applications.
15+
The next step must be to check that the called functions have a contract
16+
with an empty assigns clause and that they indeed satisfy their contract
17+
using a CI check.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <stdbool.h>
2+
3+
int foo(bool a, int *x, int *y) __CPROVER_assigns(a : *x; !a : *y)
4+
{
5+
if(a)
6+
{
7+
*x = 0; // must pass
8+
*y = 0; // must fail
9+
}
10+
else
11+
{
12+
*x = 0; // must fail
13+
*y = 0; // must pass
14+
}
15+
16+
*x = 0; // must fail
17+
*y = 0; // must fail
18+
return 0;
19+
}
20+
21+
int main()
22+
{
23+
bool a;
24+
int x;
25+
int y;
26+
27+
foo(a, &x, &y);
28+
return 0;
29+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
main.c
3+
--enforce-contract foo
4+
main.c function foo
5+
^\[foo\.\d+\] line 7 Check that \*x is assignable: SUCCESS$
6+
^\[foo\.\d+\] line 8 Check that \*y is assignable: FAILURE$
7+
^\[foo\.\d+\] line 12 Check that \*x is assignable: FAILURE$
8+
^\[foo\.\d+\] line 13 Check that \*y is assignable: SUCCESS$
9+
^\[foo\.\d+\] line 16 Check that \*x is assignable: FAILURE$
10+
^\[foo\.\d+\] line 17 Check that \*y is assignable: FAILURE$
11+
^VERIFICATION FAILED$
12+
^EXIT=10$
13+
^SIGNAL=0$
14+
--
15+
--
16+
Check that lvalue conditional assigns clause targets
17+
match with control flow path conditions.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <stdbool.h>
2+
3+
int foo(bool a, int *x, int *y) __CPROVER_assigns(a : *x, *y)
4+
{
5+
if(a)
6+
{
7+
*x = 0; // must pass
8+
*y = 0; // must pass
9+
}
10+
else
11+
{
12+
*x = 0; // must fail
13+
*y = 0; // must fail
14+
}
15+
16+
*x = 0; // must fail
17+
*y = 0; // must fail
18+
return 0;
19+
}
20+
21+
int main()
22+
{
23+
bool a;
24+
int x;
25+
int y;
26+
27+
foo(a, &x, &y);
28+
return 0;
29+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
main.c
3+
--enforce-contract foo
4+
main.c function foo
5+
^\[foo\.\d+\] line 7 Check that \*x is assignable: SUCCESS$
6+
^\[foo\.\d+\] line 8 Check that \*y is assignable: SUCCESS$
7+
^\[foo\.\d+\] line 12 Check that \*x is assignable: FAILURE$
8+
^\[foo\.\d+\] line 13 Check that \*y is assignable: FAILURE$
9+
^\[foo\.\d+\] line 16 Check that \*x is assignable: FAILURE$
10+
^\[foo\.\d+\] line 17 Check that \*y is assignable: FAILURE$
11+
^VERIFICATION FAILED$
12+
^EXIT=10$
13+
^SIGNAL=0$
14+
--
15+
--
16+
Check that conditional assigns clause `c ? {lvalue, ..}`
17+
match with control flow path conditions.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdbool.h>
2+
3+
int *identity(int *ptr)
4+
{
5+
return ptr;
6+
}
7+
8+
int foo(bool a, int *x, int offset) __CPROVER_assigns(a : !x)
9+
{
10+
return 0;
11+
}
12+
13+
int main()
14+
{
15+
bool a;
16+
int x;
17+
int y;
18+
19+
foo(a, &x, &y);
20+
return 0;
21+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--enforce-contract foo
4+
^.*error: assigns clause target must be an lvalue or __CPROVER_POINTER_OBJECT expression$
5+
^CONVERSION ERROR
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
--
10+
Checks that non-lvalue targets are rejected from conditional targets.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdbool.h>
2+
3+
int *identity(int *ptr)
4+
{
5+
return ptr;
6+
}
7+
8+
int foo(bool a, int *x, int *y) __CPROVER_assigns(a : !x, *y)
9+
{
10+
return 0;
11+
}
12+
13+
int main()
14+
{
15+
bool a;
16+
int x;
17+
int y;
18+
19+
foo(a, &x, &y);
20+
return 0;
21+
}

0 commit comments

Comments
 (0)