File tree Expand file tree Collapse file tree 10 files changed +292
-0
lines changed
function-pointer-contracts-enforce
function-pointer-contracts-replace
function-pointer-contracts-enforce
function-pointer-contracts-replace-1
function-pointer-contracts-replace-2 Expand file tree Collapse file tree 10 files changed +292
-0
lines changed Original file line number Diff line number Diff line change
1
+ #include <stdbool.h>
2
+ #include <stdlib.h>
3
+
4
+ // type of functions that manipulate arrays
5
+ typedef void (* arr_fun_t )(char * arr , size_t size );
6
+
7
+ // A contract for the arr_fun_t type
8
+ // requires a fresh array and positive size
9
+ // resets the first element to zero
10
+ void arr_fun_contract (char * arr , size_t size )
11
+ // clang-format off
12
+ __CPROVER_requires (size > 0 && __CPROVER_is_fresh (arr , size ))
13
+ __CPROVER_assigns (arr [0 ])
14
+ __CPROVER_ensures (arr [0 ] == 0 )
15
+ // clang-format on
16
+ ;
17
+
18
+ // Testing pre-conditions constructs
19
+ // Takes a function pointer as input, uses it if its preconditions are met
20
+ // to establish post-conditions
21
+ int foo (char * arr , size_t size , arr_fun_t arr_fun )
22
+ // clang-format off
23
+ __CPROVER_requires (arr == NULL || __CPROVER_is_fresh (arr , size ))
24
+ __CPROVER_requires (__CPROVER_obeys_contract (arr_fun , arr_fun_contract ))
25
+ __CPROVER_assigns (arr && size > 0 : arr [0 ])
26
+ __CPROVER_ensures ((__CPROVER_return_value == 0 ) == > (arr [0 ] == 0 ))
27
+ // clang-format on
28
+ {
29
+ int retval = -1 ;
30
+ if (arr && size > 0 )
31
+ {
32
+ CALL :
33
+ arr_fun (arr , size );
34
+ retval = 0 ;
35
+ }
36
+ return retval ;
37
+ }
38
+
39
+ void main ()
40
+ {
41
+ size_t size ;
42
+ char * arr ;
43
+ arr_fun_t fun ;
44
+ foo (arr , size , fun );
45
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --restrict-function-pointer foo.CALL/arr_fun_contract --dfcc main --enforce-contract foo
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ Checks that when a function taking a function pointer as input satisfying a given
10
+ contract is checked against its contract, the function pointer can be called
11
+ like a regular function pointer and establishes the post conditions specified
12
+ by its contract.
Original file line number Diff line number Diff line change
1
+ #include <assert.h>
2
+ #include <stdlib.h>
3
+
4
+ // type of functions that manipulate arrays
5
+ typedef void (* arr_fun_t )(char * arr , size_t size );
6
+
7
+ // A contract for the arr_fun_t type
8
+ void arr_fun_contract (char * arr , size_t size )
9
+ // clang-format off
10
+ __CPROVER_requires ((size > 0 && __CPROVER_is_fresh (arr , size )))
11
+ __CPROVER_assigns (arr [0 ])
12
+ __CPROVER_ensures (arr [0 ] == 0 )
13
+ // clang-format on
14
+ ;
15
+
16
+ arr_fun_t foo (arr_fun_t infun , arr_fun_t * outfun )
17
+ // clang-format off
18
+ __CPROVER_requires (__CPROVER_obeys_contract (infun , arr_fun_contract ))
19
+ __CPROVER_ensures (__CPROVER_obeys_contract (* outfun , arr_fun_contract ))
20
+ __CPROVER_ensures (__CPROVER_obeys_contract (__CPROVER_return_value , arr_fun_contract ))
21
+ // clang-format on
22
+ {
23
+ * outfun = arr_fun_contract ;
24
+ return infun ;
25
+ }
26
+
27
+ void main ()
28
+ {
29
+ // establish pre-conditions before replacement
30
+ arr_fun_t infun = arr_fun_contract ;
31
+
32
+ arr_fun_t outfun1 = NULL ;
33
+ arr_fun_t outfun2 = foo (infun , & outfun1 );
34
+
35
+ // checking post-conditions after replacement
36
+ assert (outfun1 == arr_fun_contract );
37
+ assert (outfun2 == arr_fun_contract );
38
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --dfcc main --replace-call-with-contract foo
4
+ ^\[main.assertion.\d+\].*assertion outfun1 == arr_fun_contract: SUCCESS$
5
+ ^\[main.assertion.\d+\].*assertion outfun2 == arr_fun_contract: SUCCESS$
6
+ ^EXIT=0$
7
+ ^SIGNAL=0$
8
+ ^VERIFICATION SUCCESSFUL$
9
+ --
10
+ --
11
+ This test checks that, when replacing a call by its contract,
12
+ requires_contract clauses are translated to equality checks
13
+ and that ensures_contract are translated to assignments of the function pointer
14
+ variable to the contract symbol.
Original file line number Diff line number Diff line change
1
+ #include <stdlib.h>
2
+
3
+ // Type of functions that manipulate arrays of a given size
4
+ typedef void (* arr_fun_t )(char * arr , size_t size );
5
+
6
+ // A contract for the arr_fun_t type
7
+ void arr_fun_contract (char * arr , size_t size )
8
+ // clang-format off
9
+ __CPROVER_requires (size > 0 && __CPROVER_is_fresh (arr , size ))
10
+ __CPROVER_assigns (arr [0 ]) __CPROVER_ensures (arr [0 ] == 0 )
11
+ // clang-format on
12
+ ;
13
+
14
+ // Uses a function pointer
15
+ int foo (char * arr , size_t size , arr_fun_t arr_fun )
16
+ // clang-format off
17
+ __CPROVER_requires (arr == > __CPROVER_is_fresh (arr , size ))
18
+ __CPROVER_requires (
19
+ arr_fun == > __CPROVER_obeys_contract (arr_fun , arr_fun_contract ))
20
+ __CPROVER_assigns (arr && size > 0 && arr_fun : arr [0 ])
21
+ __CPROVER_ensures (__CPROVER_return_value == > (arr [0 ] == 0 ))
22
+ // clang-format on
23
+ {
24
+ if (arr && size > 0 && arr_fun )
25
+ {
26
+ CALL :
27
+ arr_fun (arr , size );
28
+ return 1 ;
29
+ }
30
+ return 0 ;
31
+ }
32
+
33
+ // returns function pointer satisfying arr_fun_contract
34
+ arr_fun_t get_arr_fun ()
35
+ // clang-format off
36
+ __CPROVER_ensures (
37
+ __CPROVER_obeys_contract (__CPROVER_return_value , arr_fun_contract ))
38
+ // clang-format on
39
+ ;
40
+
41
+ // allocates an array and uses get_arr_fun and foo to initialise it
42
+ char * bar (size_t size )
43
+ // clang-format off
44
+ __CPROVER_ensures (
45
+ __CPROVER_return_value == > size > 0 &&
46
+ __CPROVER_is_fresh (__CPROVER_return_value , size ) &&
47
+ __CPROVER_return_value [0 ] == 0 )
48
+ // clang-format on
49
+ {
50
+ if (size > 0 )
51
+ {
52
+ char * arr ;
53
+ arr = malloc (size );
54
+ if (arr && foo (arr , size , get_arr_fun ()))
55
+ return arr ;
56
+
57
+ return NULL ;
58
+ }
59
+ return NULL ;
60
+ }
61
+
62
+ void main ()
63
+ {
64
+ size_t size ;
65
+ char * arr = bar (size );
66
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --dfcc main --enforce-contract bar --replace-call-with-contract foo --replace-call-with-contract get_arr_fun
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ Checks that when a function returning a function pointer satisfying a given
10
+ contract is replaced by its contract, the returned function pointer can be
11
+ passed to another function requiring the same contract.
Original file line number Diff line number Diff line change
1
+ #include <stdbool.h>
2
+ #include <stdlib.h>
3
+
4
+ // type of functions that manipulate arrays
5
+ typedef void (* arr_fun_t )(char * arr , size_t size );
6
+
7
+ // A contract for the arr_fun_t type
8
+ // requires a fresh array and positive size
9
+ // resets the first element to zero
10
+ void arr_fun_contract (char * arr , size_t size )
11
+ // clang-format off
12
+ __CPROVER_requires (size > 0 && __CPROVER_is_fresh (arr , size ))
13
+ __CPROVER_assigns (arr [0 ])
14
+ __CPROVER_ensures (arr [0 ] == 0 )
15
+ ;
16
+
17
+ // Testing pre-conditions constructs
18
+ // Takes a function pointer as input, uses it if its preconditions are met
19
+ // to establish post-conditions
20
+ int foo (char * arr , size_t size , arr_fun_t arr_fun )
21
+ // clang-format off
22
+ __CPROVER_requires (arr == NULL || __CPROVER_is_fresh (arr , size ))
23
+ __CPROVER_requires (__CPROVER_obeys_contract (arr_fun , arr_fun_contract ))
24
+ __CPROVER_assigns (arr && size > 0 : arr [0 ])
25
+ __CPROVER_ensures ((__CPROVER_return_value == 0 ) == > (arr [0 ] == 0 ))
26
+ // clang-format on
27
+ {
28
+ int retval = -1 ;
29
+ if (arr && size > 0 )
30
+ {
31
+ CALL :
32
+ arr_fun (arr , size );
33
+ retval = 0 ;
34
+ }
35
+ return retval ;
36
+ }
37
+
38
+ void main ()
39
+ {
40
+ size_t size ;
41
+ char * arr ;
42
+ arr_fun_t fun ;
43
+ foo (arr , size , fun );
44
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --enforce-contract foo --restrict-function-pointer foo.CALL/arr_fun_contract --replace-call-with-contract arr_fun_contract
4
+ ^file main.c line 23 function foo: __CPROVER_obeys_contract is not supported in this version
5
+ ^EXIT=6$
6
+ ^SIGNAL=0$
7
+ --
8
+ --
9
+ This test checks uses of the unsupported __CPROVER_obeys_contract predicate
10
+ trigger errors.
Original file line number Diff line number Diff line change
1
+ #include <assert.h>
2
+ #include <stdlib.h>
3
+
4
+ // type of functions that manipulate arrays
5
+ typedef void (* arr_fun_t )(char * arr , size_t size );
6
+
7
+ // A contract for the arr_fun_t type
8
+ void arr_fun_contract (char * arr , size_t size )
9
+ // clang-format off
10
+ __CPROVER_requires (size > 0 && __CPROVER_is_fresh (arr , size ))
11
+ __CPROVER_assigns (arr [0 ])
12
+ __CPROVER_ensures (arr [0 ] == 0 )
13
+ // clang-format on
14
+ ;
15
+
16
+ arr_fun_t get_arr_fun ()
17
+ // clang-format off
18
+ __CPROVER_ensures (
19
+ __CPROVER_obeys_contract (__CPROVER_return_value , arr_fun_contract ))
20
+ // clang-format on
21
+ ;
22
+
23
+ void foo (char * arr , size_t size )
24
+ // clang-format off
25
+ __CPROVER_requires (size > 0 && __CPROVER_is_fresh (arr , size ))
26
+ __CPROVER_assigns (arr [0 ])
27
+ __CPROVER_ensures (arr [0 ] == 0 )
28
+ // clang-format on
29
+ {
30
+ // obtain function pointer from provider
31
+ arr_fun_t arr_fun = get_arr_fun ();
32
+ // use it
33
+ CALL :
34
+ arr_fun (arr , size );
35
+ }
36
+
37
+ void main ()
38
+ {
39
+ char * arr ;
40
+ size_t size ;
41
+ foo (arr , size );
42
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --restrict-function-pointer foo.CALL/arr_fun_contract --enforce-contract foo --replace-call-with-contract get_arr_fun
4
+ ^file main.c line 19 function get_arr_fun: __CPROVER_obeys_contract is not supported in this version$
5
+ ^EXIT=6$
6
+ ^SIGNAL=0$
7
+ --
8
+ --
9
+ This test checks uses of the unsupported __CPROVER_obeys_contract predicate
10
+ trigger errors.
You can’t perform that action at this time.
0 commit comments