You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: branches/variant-submodule/doc/cprover-manual/contracts-assigns.md
+56-55Lines changed: 56 additions & 55 deletions
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@
6
6
__CPROVER_assigns(*identifier*, ...)
7
7
```
8
8
9
-
An _assigns_ clause allows the user to specify that a memory location may be written by a function. The set of locations writable by a function is the union of the locations specified by the assigns clauses, or the empty set of no _assigns_ clause is specified. While, in general, an _assigns_ clause could be interpreted with wither _writes_ or _modifies_ semantics, this
9
+
An _assigns_ clause allows the user to specify that a memory location may be written by a function. The set of locations writable by a function is the union of the locations specified by the assigns clauses, or the empty set of no _assigns_ clause is specified. While, in general, an _assigns_ clause could be interpreted with either _writes_ or _modifies_ semantics, this
10
10
design is based on the former. This means that memory not captured by an
11
11
_assigns_ clause must not be written within the given function, even if the
12
12
value(s) therein are not modified.
@@ -15,10 +15,11 @@ value(s) therein are not modified.
15
15
16
16
An _assigns_ clause currently supports simple variable types and their pointers,
17
17
structs, and arrays. Recursive pointer structures are left to future work, as
18
-
their support would require changes to CBMC's memory model. For example,
18
+
their support would require changes to CBMC's memory model.
19
19
20
20
```c
21
-
int *err_signal; // Global variable
21
+
/* Examples */
22
+
int err_signal; // Global variable
22
23
23
24
int sum(const uint32_t a, const uint32_t b, uint32_t* out)
24
25
__CPROVER_assigns(*out)
@@ -49,10 +50,10 @@ int sum(const uint32_t a, const uint32_t b, uint32_t* out)
49
50
/* Writable Set */
50
51
__CPROVER_assigns(*out)
51
52
{
52
-
const uint64_t result = ((uint64_t) a) + ((uint64_t) b);
53
-
if (result > UINT32_MAX) return FAILURE;
54
-
*out = (uint32_t) result;
55
-
return SUCCESS;
53
+
const uint64_t result = ((uint64_t) a) + ((uint64_t) b);
54
+
if (result > UINT32_MAX) return FAILURE;
55
+
*out = (uint32_t) result;
56
+
return SUCCESS;
56
57
}
57
58
```
58
59
@@ -65,28 +66,28 @@ is one of those options.
65
66
```c
66
67
int __CPROVER_contracts_original_sum(const uint32_t a, const uint32_t b, uint32_t* out)
int sum(const uint32_t a, const uint32_t b, uint32_t* out)
87
88
{
88
-
int return_value_sum = __CPROVER_contracts_original_sum(a, b, out);
89
-
return return_value_sum;
89
+
int return_value_sum = __CPROVER_contracts_original_sum(a, b, out);
90
+
return return_value_sum;
90
91
}
91
92
```
92
93
@@ -101,7 +102,8 @@ considered assignable as well.
101
102
Finally, a set of freely-assignable symbols *free* is tracked during the
102
103
traversal of the function body. These are locally-defined variables and formal
103
104
parameters without dereferences. For example, in a variable declaration `<type>
104
-
x = <initial_value>`, `x` would be added to *free*. Assignment statements where the left-hand-side is in *free* are not instrumented with the above assertions.
105
+
x = <initial_value>`, `x` would be added to the *free* set. Assignment statements
106
+
where the left-hand-side is in the *free* set are not instrumented with the above assertions.
105
107
106
108
#### Replacement
107
109
@@ -112,7 +114,7 @@ Clauses](contracts-requires-and-ensures.md) - Replacement section, and it will a
112
114
non-deterministic assignments for each object listed in the `__CPROVER_assigns`
113
115
clause. Since these objects might be modified by the function, CBMC uses
114
116
non-deterministic assignments to havoc them and restrict their values only by
115
-
assuming the postconditions.
117
+
assuming the postconditions (i.e., requires clauses).
116
118
117
119
In our example, consider that a function `foo` may call `sum`.
To specify memory footprint we use a special function called `__CPROVER_is_fresh `. The meaning of `__CPROVER_is_fresh` is that we are borrowing a pointer from the
11
-
external environment (in a precondition), or returning it to the calling context (in a postcondition).
10
+
external environment (in a precondition), or returning it to the calling context (in a postcondition).
0 commit comments