File tree 30 files changed +710
-1
lines changed
30 files changed +710
-1
lines changed Original file line number Diff line number Diff line change @@ -18,7 +18,8 @@ DIRS = cbmc \
18
18
goto-cc-cbmc \
19
19
cbmc-cpp \
20
20
goto-cc-goto-analyzer \
21
- systemc
21
+ systemc \
22
+ contracts \
22
23
# Empty last line
23
24
24
25
# Tests under goto-gcc cannot be run on Windows, so appveyor.yml unlinks
Original file line number Diff line number Diff line change
1
+ if (WIN32 )
2
+ set (is_windows true )
3
+ else ()
4
+ set (is_windows false )
5
+ endif ()
6
+
7
+ add_test_pl_tests(
8
+ "${CMAKE_CURRENT_SOURCE_DIR} /chain.sh $<TARGET_FILE:goto-cc> $<TARGET_FILE:goto-instrument> $<TARGET_FILE:cbmc> ${is_windows} "
9
+ )
Original file line number Diff line number Diff line change
1
+ default : tests.log
2
+
3
+ include ../../src/config.inc
4
+ include ../../src/common
5
+
6
+ ifeq ($(BUILD_ENV_ ) ,MSVC)
7
+ exe=../../../src/goto-cc/goto-cl
8
+ is_windows=true
9
+ else
10
+ exe=../../../src/goto-cc/goto-cc
11
+ is_windows=false
12
+ endif
13
+
14
+ test :
15
+ @../test.pl -p -c ' ../chain.sh $(exe) ../../../src/goto-instrument/goto-instrument ../../../src/cbmc/cbmc $(is_windows)'
16
+
17
+ tests.log :
18
+ @../test.pl -p -c ' ../chain.sh $(exe) ../../../src/goto-instrument/goto-instrument ../../../src/cbmc/cbmc $(is_windows)'
19
+
20
+ show :
21
+ @for dir in * ; do \
22
+ if [ -d " $$ dir" ]; then \
23
+ vim -o " $$ dir/*.c" " $$ dir/*.out" ; \
24
+ fi ; \
25
+ done ;
26
+
27
+ clean :
28
+ @for dir in * ; do \
29
+ $(RM ) tests.log; \
30
+ if [ -d " $$ dir" ]; then \
31
+ cd " $$ dir" ; \
32
+ $(RM ) * .out * .gb; \
33
+ cd ..; \
34
+ fi \
35
+ done
Original file line number Diff line number Diff line change
1
+ #! /bin/bash
2
+
3
+ set -e
4
+
5
+ goto_cc=$1
6
+ goto_instrument=$2
7
+ cbmc=$3
8
+ is_windows=$4
9
+
10
+ name=${*: $# }
11
+ name=${name% .c}
12
+
13
+ args=${*: 5: $# -5}
14
+
15
+ if [[ " ${is_windows} " == " true" ]]; then
16
+ $goto_cc " ${name} .c"
17
+ mv " ${name} .exe" " ${name} .gb"
18
+ else
19
+ $goto_cc -o " ${name} .gb" " ${name} .c"
20
+ fi
21
+
22
+ $goto_instrument ${args} " ${name} .gb" " ${name} -mod.gb"
23
+ if [ ! -e " ${name} -mod.gb" ] ; then
24
+ cp " $name .gb" " ${name} -mod.gb"
25
+ elif echo $args | grep -q -- " --dump-c" ; then
26
+ mv " ${name} -mod.gb" " ${name} -mod.c"
27
+
28
+ if [[ " ${is_windows} " == " true" ]]; then
29
+ $goto_cc " ${name} -mod.c"
30
+ mv " ${name} -mod.exe" " ${name} -mod.gb"
31
+ else
32
+ $goto_cc -o " ${name} -mod.gb" " ${name} -mod.c"
33
+ fi
34
+
35
+ rm " ${name} -mod.c"
36
+ fi
37
+ $goto_instrument --show-goto-functions " ${name} -mod.gb"
38
+ $cbmc " ${name} -mod.gb"
Original file line number Diff line number Diff line change
1
+ // function_apply_01
2
+
3
+ // Note that this test is supposed to have an incorrect contract.
4
+ // We verify that applying (without checking) the contract yields success,
5
+ // and that checking the contract yields failure.
6
+
7
+ #include <assert.h>
8
+
9
+ int foo ()
10
+ __CPROVER_ensures (__CPROVER_return_value == 0 )
11
+ {
12
+ return 1 ;
13
+ }
14
+
15
+ int main ()
16
+ {
17
+ int x = foo ();
18
+ assert (x == 0 );
19
+ return 0 ;
20
+ }
Original file line number Diff line number Diff line change
1
+ KNOWNBUG
2
+ main.c
3
+ --apply-code-contracts
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ Applying code contracts currently also checks them.
Original file line number Diff line number Diff line change
1
+ // function_check_01
2
+
3
+ // This tests a simple example of a function with requires and
4
+ // ensures which should both be satisfied.
5
+
6
+ #include <assert.h>
7
+
8
+ int min (int a , int b )
9
+ __CPROVER_requires (a >= 0 && b >= 0 )
10
+ __CPROVER_ensures (__CPROVER_return_value <= a &&
11
+ __CPROVER_return_value <= b &&
12
+ (__CPROVER_return_value == a || __CPROVER_return_value == b )
13
+ )
14
+ {
15
+ if (a <= b )
16
+ {
17
+ return a ;
18
+ }
19
+ else
20
+ {
21
+ return b ;
22
+ }
23
+ }
24
+
25
+ int main ()
26
+ {
27
+ int x , y , z ;
28
+ __CPROVER_assume (x >= 0 && y >= 0 );
29
+ z = min (x , y );
30
+ assert (z <= x );
31
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --apply-code-contracts
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ --check-code-contracts not implemented yet.
10
+ --apply-code-contracts is the current name for the flag. This should be
11
+ updated as the flag changes.
Original file line number Diff line number Diff line change
1
+ // function_check_02
2
+
3
+ // This test checks the use of quantifiers in ensures clauses.
4
+ // A known bug (resolved in PR #2278) causes the use of quantifiers
5
+ // in ensures to fail.
6
+
7
+ int initialize (int * arr )
8
+ __CPROVER_ensures (
9
+ __CPROVER_forall {int i ; (0 <= i && i < 10 ) == > arr [i ] == i }
10
+ )
11
+ {
12
+ for (int i = 0 ; i < 10 ; i ++ )
13
+ {
14
+ arr [i ] = i ;
15
+ }
16
+
17
+ return 0 ;
18
+ }
19
+
20
+ int main ()
21
+ {
22
+ int arr [10 ];
23
+ initialize (arr );
24
+ }
Original file line number Diff line number Diff line change
1
+ KNOWNBUG
2
+ main.c
3
+ --check-code-contracts
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ Ensures statements currently do not allow quantified predicates unless the
10
+ function has void return type.
Original file line number Diff line number Diff line change
1
+ // function_check_03
2
+
3
+ // This extends function_check_02's test of quantifiers in ensures
4
+ // and adds in a loop invariant which can be used to prove the ensures.
5
+ // This currently fails because side-effect checking in loop invariants is
6
+ // incorrect.
7
+
8
+ void initialize (int * arr , int len )
9
+ __CPROVER_ensures (
10
+ __CPROVER_forall {int i ; (0 <= i && i < len ) == > arr [i ] == i }
11
+ )
12
+ {
13
+ for (int i = 0 ; i < len ; i ++ )
14
+ __CPROVER_loop_invariant (
15
+ __CPROVER_forall {int j ; (0 <= j && j < i ) == > arr [j ] == j }
16
+ )
17
+ {
18
+ arr [i ] = i ;
19
+ }
20
+ }
21
+
22
+ int main ()
23
+ {
24
+ int arr [10 ];
25
+ initialize (arr , 10 );
26
+ }
Original file line number Diff line number Diff line change
1
+ KNOWNBUG
2
+ main.c
3
+ --check-code-contracts
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ Loop invariants currently do not support memory reads in at least some
10
+ circumstances.
Original file line number Diff line number Diff line change
1
+ // function_check_04
2
+
3
+ // Note that this test is supposed to have an incorrect contract.
4
+ // We verify that checking this faulty contract (correctly) yields a failure.
5
+
6
+ #include <assert.h>
7
+
8
+ int foo ()
9
+ __CPROVER_ensures (__CPROVER_return_value == 0 )
10
+ {
11
+ return 1 ;
12
+ }
13
+
14
+ int main ()
15
+ {
16
+ int x = foo ();
17
+ assert (x == 0 );
18
+ return 0 ;
19
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --apply-code-contracts
4
+ ^\[main.assertion.1\] assertion x == 0: SUCCESS$
5
+ ^\[foo.1\] : FAILURE$
6
+ ^VERIFICATION FAILED$
7
+ --
8
+ --
9
+ --check-code-contracts not implemented yet.
10
+ --apply-code-contracts is the current name for the flag. This should be
11
+ updated as the flag changes.
Original file line number Diff line number Diff line change
1
+ // function_check_05
2
+
3
+ // This test checks that when a function call is replaced by an invariant,
4
+ // it adequately havocs the locations modified by the function.
5
+ // This test currently fails because the analysis of what is modified by
6
+ // a function is flawed.
7
+
8
+ #include <assert.h>
9
+
10
+ int foo (int * x )
11
+ __CPROVER_ensures (__CPROVER_return_value == 1 )
12
+ {
13
+ * x = 1 ;
14
+ return 1 ;
15
+ }
16
+
17
+ int main ()
18
+ {
19
+ int y = 0 ;
20
+ int z = foo (& y );
21
+ // This assert should fail.
22
+ assert (y == 0 );
23
+ // This one should succeed.
24
+ assert (z == 1 );
25
+ return 0 ;
26
+ }
Original file line number Diff line number Diff line change
1
+ KNOWNBUG
2
+ main.c
3
+ --check-code-contracts
4
+ ^\[main.assertion.1\] assertion y == 0: FAILURE$
5
+ ^\[main.assertion.2\] assertion z == 1: SUCCESS$
6
+ ^\[foo.1\] : SUCCESS$
7
+ ^VERIFICATION SUCCESSFUL$
8
+ --
9
+ --
10
+ Contract checking does not properly havoc function calls.
Original file line number Diff line number Diff line change
1
+ // function_check_mem_01
2
+
3
+ // This test checks the use of pointer-related predicates in assumptions and
4
+ // requires.
5
+ // This test currently fails because of the lack of support for assuming
6
+ // pointer predicates.
7
+
8
+ #include <stddef.h>
9
+
10
+ #define __CPROVER_VALID_MEM (ptr , size ) \
11
+ __CPROVER_POINTER_OBJECT((ptr)) != __CPROVER_POINTER_OBJECT(NULL) && \
12
+ !__CPROVER_invalid_pointer((ptr)) && \
13
+ __CPROVER_POINTER_OBJECT((ptr)) != \
14
+ __CPROVER_POINTER_OBJECT(__CPROVER_deallocated) && \
15
+ __CPROVER_POINTER_OBJECT((ptr)) != \
16
+ __CPROVER_POINTER_OBJECT(__CPROVER_dead_object) && \
17
+ (__builtin_object_size((ptr), 1) >= (size) && \
18
+ __CPROVER_POINTER_OFFSET((ptr)) >= 0l || \
19
+ __CPROVER_DYNAMIC_OBJECT((ptr))) && \
20
+ (__CPROVER_POINTER_OFFSET((ptr)) >= 0 && \
21
+ __CPROVER_malloc_size >= (size) + __CPROVER_POINTER_OFFSET((ptr)) || \
22
+ __CPROVER_POINTER_OBJECT((ptr)) != \
23
+ __CPROVER_POINTER_OBJECT(__CPROVER_malloc_object))
24
+
25
+ typedef struct bar
26
+ {
27
+ int x ;
28
+ int y ;
29
+ int z ;
30
+ } bar ;
31
+
32
+ void foo (bar * x )
33
+ __CPROVER_requires (__CPROVER_VALID_MEM (x , sizeof (bar )))
34
+ {
35
+ x -> x += 1 ;
36
+ return
37
+ }
38
+
39
+ int main ()
40
+ {
41
+ bar * y ;
42
+ __CPROVER_assume (__CPROVER_VALID_MEM (y , sizeof (bar )));
43
+ y -> x = 0 ;
44
+ return 0 ;
45
+ }
Original file line number Diff line number Diff line change
1
+ KNOWNBUG
2
+ main.c
3
+ --check-code-contracts
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ --
9
+ CBMC currently does not support assumptions about pointers in the general way
10
+ that other assumptions are supported.
Original file line number Diff line number Diff line change
1
+ // invar_check_01
2
+
3
+ // This test checks that a basic loop invariant can be proven and used in
4
+ // combination with the negation of the loop guard to get a result.
5
+
6
+ #include <assert.h>
7
+
8
+ int main ()
9
+ {
10
+ int r ;
11
+ __CPROVER_assume (r >= 0 );
12
+ while (r > 0 )
13
+ __CPROVER_loop_invariant (r >= 0 )
14
+ {
15
+ -- r ;
16
+ }
17
+ assert (r == 0 );
18
+
19
+ return 0 ;
20
+ }
You can’t perform that action at this time.
0 commit comments