Skip to content

Commit 24ba3bd

Browse files
author
Remi Delmas
committed
CONTACTS: update regression test suite for DFCC
Updated tests - update assigns-enforce-malloc-zero - update assigns-local-composite - update assigns-replace-ignored-return-value - update assigns-replace-malloc-zero - update assigns-slice-targets - update assigns-slice-targets - update assigns_enforce_01 - update assigns_enforce_02 - update assigns_enforce_03 - update assigns_enforce_04 - update assigns_enforce_05 - update assigns_enforce_06 - update assigns_enforce_07
1 parent f59b93c commit 24ba3bd

File tree

19 files changed

+116
-92
lines changed

19 files changed

+116
-92
lines changed

regression/contracts/assigns-enforce-malloc-zero/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int foo(char *a, int size)
66
// clang-format off
77
__CPROVER_requires(0 <= size && size <= __CPROVER_max_malloc_size)
88
__CPROVER_requires(a == NULL || __CPROVER_is_fresh(a, size))
9-
__CPROVER_assigns(a: __CPROVER_POINTER_OBJECT(a))
9+
__CPROVER_assigns(a: __CPROVER_whole_object(a))
1010
__CPROVER_ensures(
1111
a && __CPROVER_return_value >= 0 ==> a[__CPROVER_return_value] == 0)
1212
// clang-format on

regression/contracts/assigns-enforce-malloc-zero/test.desc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract foo _ --malloc-may-fail --malloc-fail-null
4-
^\[foo.assigns.\d+\] line 9 Check that POINTER_OBJECT\(\(const void \*\)a\) is valid when a != \(\(char \*\)NULL\): SUCCESS$
3+
--dfcc main --enforce-contract foo _ --malloc-may-fail --malloc-fail-null
54
^\[foo.assigns.\d+\] line 19 Check that a\[\(signed long (long )?int\)i\] is assignable: SUCCESS$
65
^EXIT=0$
76
^SIGNAL=0$
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
CORE
22
main.c
3-
--enforce-contract foo
3+
--dfcc main --enforce-contract foo
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
77
--
88
--
9-
Checks that assigns clause checking explicitly checks assignments to locally
9+
Checks that assigns clause checking explicitly checks assignments to locally
1010
declared symbols with composite types, when they are dirty.
11-
Out of bounds accesses to locally declared arrays, structs, etc.
11+
Out of bounds accesses to locally declared arrays, structs, etc.
1212
will be detected by assigns clause checking.

regression/contracts/assigns-replace-ignored-return-value/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--replace-call-with-contract bar --replace-call-with-contract baz --enforce-contract foo
3+
--dfcc main --replace-call-with-contract bar --replace-call-with-contract baz --enforce-contract foo
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/contracts/assigns-replace-malloc-zero/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int foo(char *a, int size)
66
// clang-format off
77
__CPROVER_requires(0 <= size && size <= __CPROVER_max_malloc_size)
88
__CPROVER_requires(a == NULL || __CPROVER_rw_ok(a, size))
9-
__CPROVER_assigns(__CPROVER_POINTER_OBJECT(a))
9+
__CPROVER_assigns(__CPROVER_whole_object(a))
1010
__CPROVER_ensures(
1111
a && __CPROVER_return_value >= 0 ==> a[__CPROVER_return_value] == 0)
1212
// clang-format on

regression/contracts/assigns-replace-malloc-zero/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--replace-call-with-contract foo _ --malloc-may-fail --malloc-fail-null
3+
--dfcc main --replace-call-with-contract foo _ --malloc-may-fail --malloc-fail-null
44
^EXIT=0$
55
^SIGNAL=0$
66
\[main\.assertion\.1\] line 35 expecting SUCCESS: SUCCESS$

regression/contracts/assigns-slice-targets/test-enforce.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main-enforce.c
3-
--enforce-contract foo
3+
--dfcc main --enforce-contract foo
44
^\[foo.assigns.\d+\].* Check that s->arr1\[\(.*\)0\] is assignable: SUCCESS$
55
^\[foo.assigns.\d+\].* Check that s->arr1\[\(.*\)1\] is assignable: SUCCESS$
66
^\[foo.assigns.\d+\].* Check that s->arr1\[\(.*\)2\] is assignable: SUCCESS$

regression/contracts/assigns-slice-targets/test-replace.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main-replace.c
3-
--replace-call-with-contract foo
3+
--dfcc main --replace-call-with-contract foo
44
^\[main.assertion.\d+\].*assertion s.a == 0: SUCCESS$
55
^\[main.assertion.\d+\].*assertion \(.*\)s.arr1\[\(.*\)0\] == 0: FAILURE$
66
^\[main.assertion.\d+\].*assertion \(.*\)s.arr1\[\(.*\)1\] == 0: FAILURE$

regression/contracts/assigns_enforce_01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract foo
3+
--dfcc main --enforce-contract foo
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/contracts/assigns_enforce_02/test.desc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract foo
4-
^\[foo.assigns.\d+\] line 3 Check that z is valid: SUCCESS$
3+
--dfcc main --enforce-contract foo
54
^\[foo.assigns.\d+\] line 6 Check that \*x is assignable: FAILURE$
65
^EXIT=10$
76
^SIGNAL=0$
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract f1 --enforce-contract f2 --enforce-contract f3
4-
^\[f1.assigns.\d+\] line 1 Check that \*x1 is valid: SUCCESS$
5-
^\[f1.assigns.\d+\] line 1 Check that \*y1 is valid: SUCCESS$
6-
^\[f1.assigns.\d+\] line 1 Check that \*z1 is valid: SUCCESS$
7-
^\[f2.assigns.\d+\] line 6 Check that \*x2 is valid: SUCCESS$
8-
^\[f2.assigns.\d+\] line 6 Check that \*y2 is valid: SUCCESS$
9-
^\[f2.assigns.\d+\] line 6 Check that \*z2 is valid: SUCCESS$
10-
^\[f3.assigns.\d+\] line 11 Check that \*x3 is valid: SUCCESS$
11-
^\[f3.assigns.\d+\] line 11 Check that \*y3 is valid: SUCCESS$
12-
^\[f3.assigns.\d+\] line 12 Check that \*z3 is valid: SUCCESS$
3+
--dfcc main --enforce-contract f1
134
^\[f3.assigns.\d+\] line 14 Check that \*x3 is assignable: SUCCESS$
145
^\[f3.assigns.\d+\] line 15 Check that \*y3 is assignable: SUCCESS$
156
^\[f3.assigns.\d+\] line 16 Check that \*z3 is assignable: SUCCESS$
@@ -18,4 +9,5 @@ main.c
189
^SIGNAL=0$
1910
--
2011
--
21-
This test checks that verification succeeds when assigns clauses are respected through multiple function calls.
12+
This test checks that verification succeeds when assigns clauses are respected
13+
through multiple function calls.

regression/contracts/assigns_enforce_04/test.desc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract f1
4-
^\[f1.assigns.\d+\] line 1 Check that \*x1 is valid: SUCCESS$
5-
^\[f1.assigns.\d+\] line 1 Check that \*y1 is valid: SUCCESS$
6-
^\[f1.assigns.\d+\] line 1 Check that \*z1 is valid: SUCCESS$
3+
--dfcc main --enforce-contract f1
74
^\[f3.assigns.\d+\] line 13 Check that \*x3 is assignable: SUCCESS$
85
^\[f3.assigns.\d+\] line 14 Check that \*y3 is assignable: SUCCESS$
96
^\[f3.assigns.\d+\] line 15 Check that \*z3 is assignable: SUCCESS$

regression/contracts/assigns_enforce_05/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract f1 --enforce-contract f2 --enforce-contract f3
3+
--dfcc main --enforce-contract f1
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,44 @@
1-
void f1(int *x1, int *y1, int *z1) __CPROVER_assigns(*x1, *y1, *z1)
1+
void f1(int *x, int *y, int *z) __CPROVER_assigns(*x, *y, *z)
22
{
3-
f2(x1, y1, z1);
3+
f2(x, y, z);
44
}
55

6-
void f2(int *x2, int *y2, int *z2) __CPROVER_assigns(*x2, *y2, *z2)
6+
void f2(int *x, int *y, int *z) __CPROVER_assigns(*x, *y, *z)
77
{
8-
f3(x2, y2, z2);
8+
f3(x, y, z);
99
}
1010

11-
void f3(int *x3, int *y3, int *z3) __CPROVER_assigns(*x3, *y3, *z3)
11+
void f3(int *x, int *y, int *z) __CPROVER_assigns(*x, *y, *z)
1212
{
13-
*x3 = *x3 + 1;
14-
*y3 = *y3 + 1;
15-
*z3 = *z3 + 1;
13+
*x = *x + 1;
14+
*y = *y + 1;
15+
*z = *z + 1;
1616
}
1717

18-
int main()
18+
void f(int *x, int *y, int *z) __CPROVER_assigns(*x, *y, *z)
1919
{
20-
int p = 1;
21-
int q = 2;
22-
int r = 3;
23-
2420
for(int i = 0; i < 3; ++i)
2521
{
2622
if(i == 0)
2723
{
28-
f1(&p, &q, &r);
24+
f1(x, y, z);
2925
}
3026
if(i == 1)
3127
{
32-
f2(&p, &q, &r);
28+
f2(x, y, z);
3329
}
3430
if(i == 2)
3531
{
36-
f3(&p, &q, &r);
32+
f3(x, y, z);
3733
}
3834
}
35+
}
3936

37+
int main()
38+
{
39+
int p = 1;
40+
int q = 2;
41+
int r = 3;
42+
f(&p, &q, &r);
4043
return 0;
4144
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
CORE
22
main.c
3-
--enforce-contract f1 --enforce-contract f2 --enforce-contract f3
3+
--dfcc main --enforce-contract f
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
77
--
88
--
9-
This test checks that verification succeeds when functions with assigns clauses are called from within a loop.
9+
This test checks that verification succeeds when functions
10+
are called from within a loop.
Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,46 @@
1-
void f1(int *x1, int *y1, int *z1) __CPROVER_assigns(*x1, *y1, *z1)
1+
void f1(int *x, int *y, int *z) __CPROVER_assigns(*x, *y)
22
{
3-
f2(x1, y1, z1);
3+
*x = *x + 1;
4+
*y = *y + 1;
45
}
56

6-
void f2(int *x2, int *y2, int *z2) __CPROVER_assigns(*x2, *y2, *z2)
7+
void f2(int *x, int *y, int *z) __CPROVER_assigns(*x, *y)
78
{
8-
f3(x2, y2, z2);
9+
*x = *x + 1;
10+
*y = *y + 1;
911
}
1012

11-
void f3(int *x3, int *y3, int *z3) __CPROVER_assigns(*y3, *z3)
13+
void f3(int *x, int *y, int *z) __CPROVER_assigns(*x, *y, *z)
1214
{
13-
*x3 = *x3 + 1;
14-
*y3 = *y3 + 1;
15-
*z3 = *z3 + 1;
15+
*x = *x + 1;
16+
*y = *y + 1;
17+
*z = *z + 1;
1618
}
1719

18-
int main()
20+
void f(int *x, int *y, int *z) __CPROVER_assigns(*x, *y)
1921
{
20-
int p = 1;
21-
int q = 2;
22-
int r = 3;
23-
2422
for(int i = 0; i < 3; ++i)
2523
{
2624
if(i == 0)
2725
{
28-
f1(&p, &q, &r);
26+
f1(x, y, z);
2927
}
3028
if(i == 1)
3129
{
32-
f2(&p, &q, &r);
30+
f2(x, y, z);
3331
}
3432
if(i == 2)
3533
{
36-
f3(&p, &q, &r);
34+
f3(x, y, z);
3735
}
3836
}
37+
}
3938

39+
int main()
40+
{
41+
int p = 1;
42+
int q = 2;
43+
int r = 3;
44+
f(&p, &q, &r);
4045
return 0;
4146
}

regression/contracts/assigns_enforce_07/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--enforce-contract f1 --enforce-contract f2 --enforce-contract f3
3+
--dfcc main --enforce-contract f
44
^EXIT=10$
55
^SIGNAL=0$
66
^VERIFICATION FAILED$

regression/contracts/frees-clause-and-predicates/main.c

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,75 @@
1+
#include <stdbool.h>
12
#include <stdlib.h>
23

3-
// A function defining a conditionally freeable target
4-
__CPROVER_freeable_t
5-
foo_frees(char *arr, const size_t size, const size_t new_size)
4+
// A function defining an assignable target
5+
__CPROVER_assignable_t foo_assigns(char *arr, const size_t size)
6+
{
7+
__CPROVER_object_upto(arr, size);
8+
}
9+
10+
// A function defining an freeable target
11+
__CPROVER_freeable_t foo_frees(char *arr, const size_t size)
612
{
713
__CPROVER_freeable(arr);
814
}
915

10-
char *foo(char *arr, const size_t size, const size_t new_size)
16+
bool is_freeable(void *ptr)
17+
{
18+
bool is_dynamic_object = (ptr == 0) | __CPROVER_DYNAMIC_OBJECT(ptr);
19+
bool has_offset_zero = (ptr == 0) | (__CPROVER_POINTER_OFFSET(ptr) == 0);
20+
return is_dynamic_object & has_offset_zero;
21+
}
22+
23+
char *foo(char *ptr, const size_t size, const size_t new_size)
1124
// clang-format off
12-
__CPROVER_requires(__CPROVER_is_freeable(arr))
13-
__CPROVER_assigns(__CPROVER_whole_object(arr))
14-
__CPROVER_frees(foo_frees(arr, size, new_size))
25+
__CPROVER_requires(__CPROVER_is_freeable(ptr))
26+
__CPROVER_assigns(foo_assigns(ptr, size))
27+
__CPROVER_frees(foo_frees(ptr, size))
1528
__CPROVER_ensures(
16-
(arr && new_size > size) ==>
29+
(ptr && new_size > size) ==>
1730
__CPROVER_is_fresh(__CPROVER_return_value, new_size))
1831
__CPROVER_ensures(
19-
(arr && new_size > size) ==>
20-
__CPROVER_is_freed(__CPROVER_old(arr)))
32+
(ptr && new_size > size) ==>
33+
__CPROVER_is_freed(ptr))
2134
__CPROVER_ensures(
22-
!(arr && new_size > size) ==>
23-
__CPROVER_return_value == __CPROVER_old(arr))
35+
!(ptr && new_size > size) ==>
36+
__CPROVER_return_value == __CPROVER_old(ptr))
2437
// clang-format on
2538
{
26-
if(arr && new_size > size)
39+
// The harness allows to add a nondet offset to the pointer passed to foo.
40+
// Proving this assertion shows that the __CPROVER_is_freeable(ptr) assumption
41+
// is in effect as expected for the verification
42+
__CPROVER_assert(is_freeable(ptr), "ptr is freeable");
43+
44+
if(ptr && new_size > size)
2745
{
28-
free(arr);
29-
return malloc(new_size);
46+
free(ptr);
47+
ptr = malloc(new_size);
48+
49+
// write at some nondet i (should be always allowed since ptr is fresh)
50+
size_t i;
51+
if(i < new_size)
52+
ptr[i] = 0;
53+
54+
return ptr;
3055
}
3156
else
3257
{
33-
return arr;
58+
// write at some nondet i
59+
size_t i;
60+
if(i < size)
61+
ptr[i] = 0;
62+
63+
return ptr;
3464
}
3565
}
3666

3767
int main()
3868
{
3969
size_t size;
4070
size_t new_size;
71+
__CPROVER_assume(size < __CPROVER_max_malloc_size);
72+
__CPROVER_assume(new_size < __CPROVER_max_malloc_size);
4173
char *arr = malloc(size);
4274
arr = foo(arr, size, new_size);
4375
return 0;
Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
CORE
22
main.c
3-
--enforce-contract foo
4-
^\[foo.postcondition.\d+\] line \d+ Check ensures clause: FAILURE$
5-
^VERIFICATION FAILED$
6-
^EXIT=10$
3+
-dfcc main --enforce-contract foo
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
76
^SIGNAL=0$
87
--
98
--
10-
This test checks that the front end parses and typchecks correct uses of:
9+
This test checks that using the -dffdfcc flag we can check contracts that use:
1110
- __CPROVER_freeable_t function calls as frees clause targets
12-
- the predicate __CPROVER_freeable
13-
- the predicate __CPROVER_is_freeable
14-
- the predicate __CPROVER_is_freed
15-
16-
The post condition of the contract is expected to fail because the predicates
17-
have no interpretation in the back-end yet.
11+
- the __CPROVER_freeable built-in
12+
- the __CPROVER_is_freeable built-in predicate
13+
- the __CPROVER_is_freed built-in predicate

0 commit comments

Comments
 (0)