File tree 2 files changed +87
-0
lines changed
regression/contracts-dfcc/recursive-function-and-loop-contracts
2 files changed +87
-0
lines changed Original file line number Diff line number Diff line change
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
+ }
Original file line number Diff line number Diff line change
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
You can’t perform that action at this time.
0 commit comments