Skip to content

Commit d288ba0

Browse files
author
Remi Delmas
committed
CONTRACTS: test combination of loop contracts and recursive functions
1 parent 5affe65 commit d288ba0

File tree

2 files changed

+87
-0
lines changed
  • regression/contracts-dfcc/recursive-function-and-loop-contracts

2 files changed

+87
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <assert.h>
2+
#include <stdbool.h>
3+
#include <stdlib.h>
4+
5+
bool nondet_bool();
6+
7+
int foo(char *arr, const size_t size, size_t offset)
8+
// clang-format off
9+
__CPROVER_requires( 0 < size && offset <= size && __CPROVER_is_fresh(arr, size))
10+
__CPROVER_assigns(__CPROVER_object_whole(arr))
11+
// clang-format on
12+
{
13+
if(offset == 0)
14+
return 0;
15+
16+
// recursive call
17+
foo(arr, size, offset - 1);
18+
19+
size_t i1 = offset;
20+
while(i1 < size)
21+
// clang-format off
22+
__CPROVER_assigns(i1, __CPROVER_object_whole(arr))
23+
__CPROVER_loop_invariant(i1 <= size)
24+
__CPROVER_decreases(size - i1)
25+
// clang-format on
26+
{
27+
static int local_static = 0;
28+
local_static = 1;
29+
arr[i1] = 1;
30+
size_t i2 = offset;
31+
while(i2 < size)
32+
//clang-format off
33+
__CPROVER_assigns(i2, __CPROVER_object_whole(arr))
34+
__CPROVER_loop_invariant(i2 <= size) __CPROVER_decreases(size - i2)
35+
//clang-format on
36+
{
37+
local_static = 2;
38+
arr[i2] = 2;
39+
i2++;
40+
}
41+
bool must_break = nondet_bool();
42+
if(must_break)
43+
{
44+
size_t i3 = offset;
45+
while(i3 < size)
46+
// clang-format off
47+
__CPROVER_assigns(i3, __CPROVER_object_whole(arr))
48+
__CPROVER_loop_invariant(i3 <= size)
49+
__CPROVER_decreases(size - i3)
50+
// clang-format on
51+
{
52+
local_static = 3;
53+
arr[i3] = 3;
54+
i3++;
55+
}
56+
break;
57+
}
58+
i1++;
59+
}
60+
}
61+
62+
int main()
63+
{
64+
char *arr;
65+
size_t size;
66+
size_t offset;
67+
foo(arr, size, offset);
68+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
THOROUGH dfcc-only
2+
main.c
3+
--dfcc main --enforce-contract-rec foo --apply-loop-contracts --malloc-may-fail --malloc-fail-null _ --bounds-check --pointer-check --signed-overflow-check --unsigned-overflow-check --conversion-check --sat-solver cadical
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
This test illustrates the analysis of a function with a combination of features:
10+
- the function is recursive
11+
- the function contains loops
12+
- the function assigns local static variables
13+
14+
The following write set checks are performed:
15+
- the write set of the recursive call is included in the caller'set
16+
- the write set of each loop is included in the outer write set, either the
17+
function's write set or some loop's write set)
18+
- local statics are automatically detected and added to each write set
19+
- the instructions are checked against their respective write sets

0 commit comments

Comments
 (0)