CBMC
|
Back to top Code Contracts Transformation Specification
The front end allows to express parametric assignable sets and freeable sets declaratively by calling special built-ins from regular C functions, as described in Assigns Clauses and Frees Clauses.
Such functions require a rewriting pass in order to turn them into active functions that can effectively populate a write set with new targets.
GOTO functions which specify assignable locations have the following type signature:
They can be generated from an assigns clause or written by the user.
To convert them to active functions, the first step is to inline their body and remove all function calls, the result of which must be loop-free.
Then, a second pass adds the write set to be filled as new parameter to the function:
In the inlined body, calls to built in functions __CPROVER_assignable
, __CPROVER_object_upto
, __CPROVER_object_from
, __CPROVER_object_whole
are numbered from 0 to N in increasing order from their position in the instruction sequence:
They are then rewritten into calls to the corresponding instrumentation hook provided by the cprover_contracts.c library:
The function is then instrumented as described in GOTO Function Instrumentation which adds a second write set parameter, that allows to check that the function has no unintended side effects.
Contract replacement requires havocing the set of targets described in an assigns clause. Since there can exist dependencies and aliasing between the different targets, in order to havoc them in parallel, we first need to snapshot the target locations into a write set data structure, and generate a function that can havoc these snapshotted locations in a second step.
GOTO functions which specify assignable locations have the following type signature:
They can be generated from an assigns clause or written by the user.
To convert them to havoc functions, the first step is to inline their body and remove all function calls, the result of which must be loop-free.
Then, a second pass adds the write set to be havoced as new parameter to the function:
In the inlined body, calls to built in functions __CPROVER_assignable
, __CPROVER_object_upto
, __CPROVER_object_from
, __CPROVER_object_whole
are numbered from 0 to N in increasing order from their position in the instruction sequence:
They are then rewritten into calls to the corresponding instrumentation hook provided by the cprover_contracts.c library:
Targets specified with __CPROVER_object_whole
:
Get rewritten to:
Targets specified with __CPROVER_object_from
or __CPROVER_object_upto
:
Get rewritten to:
Last, targets specified with __CPROVER_assignable
Get rewritten to a typed nondeterministic assignment:
The generated function has the intended side effects by construction and nothing else.
User-defined functions which list freeable pointers have the following signature:
They are first inlined and checked to be loop free before being rewritten into functions which accepts a write set parameter to be filled with freeable targets defined by the function:
Calls to the built-in function:
are rewritten into to calls to active instrumentation functions which insert into the write set
The function is then instrumented as described in GOTO Function Instrumentation which adds a second write set parameter, that allows to check that the function has no unintended side effects.
Prev | Next |
---|---|
Generating GOTO Functions From Contract Clauses | Rewriting User-Defined Memory Predicates |