File tree Expand file tree Collapse file tree 2 files changed +87
-0
lines changed
regression/contracts-dfcc/recursive-function-and-loop-contracts Expand file tree Collapse file tree 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