Skip to content

Commit d50ecfa

Browse files
author
Remi Delmas
committed
CONTRACTS: Add doxygen doc for DFCC
User doc and developer doc now live in doxygen land.
1 parent 344456e commit d50ecfa

31 files changed

+1906
-271
lines changed

doc/cprover-manual/contracts-requires-and-ensures.md

Lines changed: 0 additions & 136 deletions
This file was deleted.

src/doxyfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ WARN_LOGFILE =
772772
# Note: If this tag is empty the current directory is searched.
773773

774774
INPUT = . ../doc ../jbmc/src ../unit/testing-utils ../jbmc/unit/java-testing-utils
775+
INPUT += ansi-c/library/cprover_contracts.c
775776

776777
# This tag can be used to specify the character encoding of the source files
777778
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
[CPROVER Manual TOC](../)
2-
3-
# Contracts
1+
# Code Contracts in CBMC {#contracts-mainpage}
42

53
Code contracts in CBMC provide way to safely abstract parts of a program,
64
typically in order to accelerate the verification process.
@@ -14,10 +12,8 @@ notes [Contract-based
1412
Design](https://www.georgefairbanks.com/york-university-contract-based-design-2021)
1513
by George Fairbanks.
1614

17-
CBMC currently supports contracts on functions and loops:
18-
19-
- [Function Contracts](../contracts/functions/)
20-
- [Loop Contracts](../contracts/loops/)
21-
2215
For extra steps required to compositionally reason about file-local functions
23-
[see](static-functions/).
16+
[please consult this link](todo-link-to-cprover-manual-static-functions).
17+
18+
- @subpage contracts-user
19+
- @subpage contracts-dev
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Code Contracts Software Architecture {#contracts-dev-arch}
2+
3+
Back to @ref contracts-dev
4+
5+
@tableofcontents
6+
7+
## Architecture Overview
8+
9+
The code implementing @ref contracts-dev-spec is found in @ref dfcc-module
10+
11+
We go over each class and explain how it works in relation to others.
12+
13+
The @ref dfcct class is the main entry point into the transformation.
14+
15+
The method @ref dfcct#transform_goto_model first separates the functions of the goto model in different groups (functions to instrument, pure contract symbols from which to generate code, functions to check against contracts, functions to replace with contracts) and applies the transformation
16+
to the whole goto model, by scheduling the translation passes
17+
described in @ref contracts-dev-spec :
18+
19+
1. @ref contracts-dev-spec-codegen is applied to all contracts to check or replace;
20+
2. @ref contracts-dev-spec-dfcc is applied to all library or user-defined goto functions;
21+
3. @ref contracts-dev-spec-harness is applied to the harness function;
22+
4. @ref contracts-dev-spec-contract-checking is applied to the function to be checked against a contract;
23+
5. @ref contracts-dev-spec-contract-replacement is applied to each function to be replaced by a contract;
24+
25+
Each of these translation passes is implemented in a specific class:
26+
27+
Class | Specification
28+
:-------------------------------|:---------------------------------------
29+
@ref dfcc_instrumentt | Implements @ref contracts-dev-spec-dfcc for @ref goto_functiont, @ref goto_programt, or subsequences of instructions of @ref goto_programt
30+
@ref dfcc_is_fresht | Implements @ref contracts-dev-spec-is-fresh
31+
@ref dfcc_is_freeablet | Implements @ref contracts-dev-spec-is-freeable
32+
@ref dfcc_spec_functionst | Implements @ref contracts-dev-spec-spec-rewriting
33+
@ref dfcc_dsl_wrapper_programt | Implements @ref contracts-dev-spec-contract-checking for DSL-style contracts
34+
^ | Implements @ref contracts-dev-spec-contract-replacement for DSL-style contracts
35+
@ref dfcc_dsl_contract_handlert | Implements @ref contracts-dev-spec-codegen for DSL-style contracts
36+
^ | Implements the interface @ref dfcc_contract_handlert for DSL-style contract by delegating operations to @ref dfcc_dsl_wrapper_programt
37+
@ref dfcc_swap_and_wrapt | Implements @ref contracts-dev-spec-contract-checking by delegating basic operations to @ref dfcc_contract_handlert
38+
^ | Implements @ref contracts-dev-spec-contract-replacement by delegating basic operations to @ref dfcc_contract_handlert
39+
^ | Implements @ref contracts-dev-spec-contract-checking-rec by delegating basic operations to @ref dfcc_contract_handlert
40+
41+
The following classes contain utility methods:
42+
- @ref dfcc_utilst : Provides basic utility methods to the other classes such as
43+
locating a function symbol, adding a parameter to a function symbol, cloning
44+
or renaming a function symbol, creating fresh symbols, inlining a function
45+
body, etc.
46+
- @ref dfcc_libraryt : Provides a C++ interface to access C library functions
47+
defined in @ref cprover_contracts.c. Using this class it is possible to load
48+
the library symbols and post-process them with loop unrolling or inlining, etc.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Generating GOTO Functions From Contract Clauses {#contracts-dev-spec-codegen}
2+
3+
Back to top @ref contracts-dev-spec
4+
5+
@tableofcontents
6+
7+
## Translating Assigns Clauses to GOTO Functions {#contracts-dev-spec-codegen-assigns}
8+
9+
10+
Let's consider a contract `foo` (with corresponding pure contract
11+
`contract::foo`) with a `__CPROVER_assigns(A)` clause.
12+
13+
```c
14+
ret_t foo(foo-parameters) __CPROVER_assigns(A);
15+
```
16+
We know the elements of A only depend on `foo-parameters` and global variables.
17+
18+
A new GOTO function with the following signature is generated:
19+
20+
```c
21+
void contract::foo::assigns(foo-parameters);
22+
```
23+
24+
The body of the function generated from the elements of A as follows:
25+
- For each target `cond: target` where the target is an lvalue expression:
26+
```c
27+
DECL __cond: bool;
28+
ASSIGN __cond = <result of goto_convert(cond)>;
29+
IF !__cond GOTO SKIP_TARGET;
30+
CALL __CPROVER_assignable(&target, sizeof(target), has_ptr_type(target));
31+
SKIP_TARGET: SKIP;
32+
DEAD __cond;
33+
```
34+
where `has_ptr_type(target)` returns true if the target has a pointer-type;
35+
- For each target `cond: f(parameters)`, where `f` is a void-typed function:
36+
```c
37+
DECL __cond: bool;
38+
ASSIGN __cond = <result of goto_convert(cond)>;
39+
IF !__cond GOTO SKIP_TARGET;
40+
CALL f(parameters);
41+
SKIP_TARGET: SKIP;
42+
DEAD __cond;
43+
```
44+
45+
Remark: The condition expressions needs to be goto_converted during translation
46+
since they come directly from the front-end and are allowed to contain function
47+
calls.
48+
49+
The rewriting pass @ref contracts-dev-spec-spec-rewriting-assigns is applied
50+
to transform the function into a function that accepts two
51+
write set parameters: The first one is the write set that gets populated with
52+
assignable locations specified by the function, the second is a write set that
53+
is used by the function to check its side effects.
54+
55+
```c
56+
void contract::foo::assigns(
57+
58+
// function parameters
59+
foo-parameters,
60+
61+
// write set to populate with new targets
62+
__CPROVER_contracts_write_set_ptr_t __write_set_to_fill,
63+
64+
// write set against which to check itself for unwanted side effects
65+
__CPROVER_contracts_write_set_ptr_t __write_set_to_check);
66+
```
67+
68+
The rewriting step @ref contracts-dev-spec-spec-rewriting-havoc is also applied
69+
to the function in order to generate a havoc function that can be used to model
70+
contract replacement:
71+
72+
```c
73+
void contract::foo::havoc(__CPROVER_contracts_write_set_ptr_t __write_set_to_havoc);
74+
```
75+
76+
## Translating Frees Clauses to GOTO Functions {#contracts-dev-spec-codegen-frees}
77+
78+
Let's consider a contract `foo` (with corresponding pure contract
79+
`contract::foo`) with a `__CPROVER_frees(F)` clause.
80+
81+
```c
82+
ret_t foo(foo-parameters) __CPROVER_frees(F);
83+
```
84+
We know the elements of F only depend on `foo-parameters` and global variables.
85+
86+
A new GOTO function with the following signature is generated:
87+
88+
```c
89+
void contract::foo::frees(foo-parameters);
90+
```
91+
92+
The body of the function generated from the elements of F as follows:
93+
- For each element of the form `cond: expr` where `expr` is a pointer-typed
94+
expression:
95+
```c
96+
DECL __cond: bool;
97+
ASSIGN __cond = <result of goto_convert(cond)>;
98+
IF !__cond GOTO SKIP_TARGET;
99+
CALL __CPROVER_freeable(expr);
100+
SKIP_TARGET: SKIP;
101+
DEAD __cond;
102+
```
103+
- For each target of the form `cond: f(params)` where `f` is a void-typed
104+
function:
105+
```c
106+
DECL __cond: bool;
107+
ASSIGN __cond = <result of goto_convert(cond)>;
108+
IF !__cond GOTO SKIP_TARGET;
109+
CALL f(params);
110+
SKIP_TARGET: SKIP;
111+
DEAD __cond;
112+
```
113+
114+
Remark: The condition expressions needs to be goto_converted during translation
115+
since they come directly from the front-end and are allowed to contain function
116+
calls.
117+
118+
The resulting function is declarative, in the sense that it describes the
119+
contents of the frees clause but does not have any runtime effects.
120+
121+
The rewriting pass @ref contracts-dev-spec-spec-rewriting-frees is applied
122+
to transform the function into a function that accepts two
123+
write set parameters: The first one is the write set that gets populated with
124+
freeable pointers specified by the function, the second is a write set that is
125+
used by the function to check its side effects.
126+
127+
```c
128+
void contract::foo::frees(
129+
130+
// function parameters
131+
foo-parameters,
132+
133+
// write set to populate with new targets
134+
__CPROVER_contracts_write_set_ptr_t __write_set_to_fill,
135+
136+
// write set against which to check itself for unwanted side effects
137+
__CPROVER_contracts_write_set_ptr_t __write_set_to_check);
138+
```
139+
140+
---
141+
Prev | Next
142+
:-----|:------
143+
@ref contracts-dev-spec-transfo-params | @ref contracts-dev-spec-spec-rewriting

0 commit comments

Comments
 (0)