Skip to content

Commit 37c0b83

Browse files
authored
Merge pull request #2309 from qaphla/regression
Regression tests for code contracts
2 parents be6f3c9 + d49ea09 commit 37c0b83

File tree

30 files changed

+710
-1
lines changed

30 files changed

+710
-1
lines changed

regression/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ DIRS = cbmc \
1818
goto-cc-cbmc \
1919
cbmc-cpp \
2020
goto-cc-goto-analyzer \
21-
systemc
21+
systemc \
22+
contracts \
2223
# Empty last line
2324

2425
# Tests under goto-gcc cannot be run on Windows, so appveyor.yml unlinks

regression/contracts/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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+
)

regression/contracts/Makefile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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

regression/contracts/chain.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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.

0 commit comments

Comments
 (0)