Skip to content

Commit 3ce7307

Browse files
committed
Revamp function contracts interface
This commit adds four new flags to goto-instrument that allow CBMC to check or take advantage of function contracts in the target codebase. It prepares for a series of commits that will improve the soundness of this functionality and add support for loop invariants. The motivation behind this patch series is to improve scalability of code verification. Given the following code: foo() __CPROVER_ensures(P) __CPROVER_ensures(Q) { ... } bar() { foo(); } the user can pass `--replace-call-with-contract foo` to goto-instrument, which will change the body of `bar` so that it can be verified more scalably: bar() { assert(P); assume(Q); } The user should then separately pass `--enforce-contract foo` to goto-instrument. This instruments `foo` so that it looks like this: foo() { assume(P); // original body assert(Q); } Running `cbmc --function foo` on the instrumented binary then checks that `foo` actually abides by its contract, regardless of its calling context. Users can also pass `--enforce-all-contracts` and `--replace-all-calls-with-contracts` to avoid naming every function.
1 parent dbac963 commit 3ce7307

File tree

15 files changed

+384
-87
lines changed

15 files changed

+384
-87
lines changed

regression/contracts/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
if(WIN32)
2-
set(is_windows true)
2+
set(is_windows true)
33
else()
4-
set(is_windows false)
4+
set(is_windows false)
55
endif()
66

77
add_test_pl_tests(

regression/contracts/function_apply_01/main.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
#include <assert.h>
88

9-
int foo()
10-
__CPROVER_ensures(__CPROVER_return_value == 0)
9+
int foo() __CPROVER_ensures(__CPROVER_return_value == 0)
1110
{
1211
return 1;
1312
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--apply-code-contracts
3+
--replace-all-calls-with-contracts
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
77
--
8+
^warning: ignoring
89
--
9-
Applying code contracts currently also checks them.
10+
This code is purposely unsound (the function does not abide by its
11+
contract). Verifying the function in isolation should fail, and
12+
verifying its caller should succeed.

regression/contracts/function_check_01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--apply-code-contracts
44
^EXIT=0$

regression/contracts/function_check_04/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--apply-code-contracts
44
^EXIT=10$
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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() __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+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[main.assertion.1\] line 17 assertion x == 0: FAILURE$
7+
^VERIFICATION FAILED$
8+
--
9+
^warning: ignoring
10+
--
11+
We don't actually replace the function call with its contract here, so
12+
CBMC should notice that the program is unsound.

regression/contracts/invar_check_01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--apply-code-contracts
44
^EXIT=0$

regression/contracts/invar_check_02/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--apply-code-contracts
44
^EXIT=0$

regression/contracts/invar_check_03/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--apply-code-contracts
44
^EXIT=0$

regression/contracts/invar_check_04/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--apply-code-contracts
44
^EXIT=10$

0 commit comments

Comments
 (0)