Skip to content

Commit e835e6b

Browse files
WIP Add some information about new option to the manual
1 parent 38ee140 commit e835e6b

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

doc/cprover-manual.md

+156
Original file line numberDiff line numberDiff line change
@@ -2679,6 +2679,162 @@ Flag | Check
26792679
`--uninitialized-check` | add checks for uninitialized locals (experimental)
26802680
`--error-label label` | check that given label is unreachable
26812681

2682+
#### Generating/Replacing function bodies
2683+
2684+
Sometimes implementations for called functions are not available in the goto
2685+
program, or it is desirable to replace bodies of functions with certain
2686+
predetermined stubs (for example to confirm that these functions are never
2687+
called, or to indicate that these functions will never return). For this purpose
2688+
goto-instrument provides the `--generate-function-body` and
2689+
`--replace-function-body` options, that take a regular expression (in
2690+
[ECMAScript syntax](http://en.cppreference.com/w/cpp/regex/ecmascript)) that
2691+
describes the names of the functions to generate or replace, the difference
2692+
being that `--generate-function-body` will only generate bodies of functions
2693+
that do not already have one, whereas `--replace-function-body` will do this and
2694+
in addition also replace existing bodies of functions with the stub.
2695+
2696+
The shape of the stub itself can be chosen with the `--replace-function-body-options`
2697+
parameter, which can take the following values:
2698+
2699+
Option | Result
2700+
-----------------------------|-------------------------------------------------------------
2701+
`nondet-return` | Do nothing and return a nondet result (this is the default)
2702+
`empty` | Delete the body of the function
2703+
`assert-false` | Make the body contain an assert(false)
2704+
`assume-false` | Make the body contain an assume(false)
2705+
`assert-false-assume-false` | Combines assert-false and assume-false
2706+
`havoc` | Set the contents of parameters and globals to nondet
2707+
2708+
The various combinations of assert-false and assume-false can be used to
2709+
indicate that functions shouldn't be called, that they will never return or
2710+
both.
2711+
2712+
Example: We have a program like this:
2713+
2714+
// error_example.c
2715+
#include <stdlib.h>
2716+
2717+
void api_error(void);
2718+
void internal_error(void);
2719+
2720+
int main(void)
2721+
{
2722+
int arr[10] = {1,2,3,4,5, 6, 7, 8, 9, 10};
2723+
int sum = 0;
2724+
for(int i = 1; i < 10; ++i)
2725+
{
2726+
sum += arr[i];
2727+
}
2728+
if(sum != 55)
2729+
{
2730+
// we made a mistake when calculating the sum
2731+
internal_error();
2732+
}
2733+
if(rand() < 0)
2734+
{
2735+
// we think this cannot happen
2736+
api_error();
2737+
}
2738+
return 0;
2739+
}
2740+
2741+
Now, we can compile the program and detect that the error functions are indeed
2742+
called by invoking these commands
2743+
2744+
goto-cc error_example.c -o error_example.goto
2745+
# Replace all functions ending with _error
2746+
# (Excluding those starting with __)
2747+
# With ones that have an assert(false) body
2748+
goto-instrument error_example.goto error_example_replaced.goto \
2749+
--replace-function-body '(?!__).*_error' \
2750+
--replace-function-body-options assert-false
2751+
cbmc error_example_replaced.goto
2752+
2753+
Which gets us the output
2754+
2755+
> ** Results:
2756+
> [internal_error.assertion.1] assertion false: FAILURE
2757+
> [api_error.assertion.1] assertion false: FAILURE
2758+
>
2759+
>
2760+
> ** 2 of 2 failed (2 iterations)
2761+
> VERIFICATION FAILED
2762+
2763+
As opposed to the verification success we would have gotten without the
2764+
replacement
2765+
2766+
2767+
The havoc option takes further parameters `globals` and `params` with this
2768+
syntax: `havoc[,globals:<regex>][,params:<regex>]` (where the square brackets
2769+
indicate an optional part). The regular expressions have the same format as the
2770+
those for the `--replace-function-body` and `--generate-function-body` options
2771+
and indicate which globals and function parameters should be set to nondet. All
2772+
regular expressions require exact matches (i.e. the regular expression `ab?`
2773+
will match 'a' and 'b' but not 'adrian' or 'bertha').
2774+
2775+
Example: With a C program like this
2776+
2777+
struct Complex {
2778+
double real;
2779+
double imag;
2780+
};
2781+
2782+
struct Complex AGlobalComplex;
2783+
int do_something_with_complex(struct Complex *complex);
2784+
2785+
And the command line
2786+
2787+
goto-instrument in.goto out.goto
2788+
--replace-function-body do_something_with_complex
2789+
--replace-function-body-options
2790+
'havoc,params:.*,globals:AGlobalComplex'
2791+
2792+
The goto code equivalent of the following will be generated:
2793+
2794+
int do_something_with_complex(struct Complex *complex)
2795+
{
2796+
if(complex)
2797+
{
2798+
complex->real = nondet_double();
2799+
complex->imag = nondet_double();
2800+
}
2801+
return nondet_int();
2802+
}
2803+
2804+
A note on limitations: Because only static information is used for code
2805+
generation, arrays of unknown size and pointers will not be affected by this;
2806+
Which means that for code like this:
2807+
2808+
struct Node {
2809+
int val;
2810+
struct Node *next;
2811+
};
2812+
2813+
void do_something_with_node(struct Node *node);
2814+
2815+
Code like this will be generated:
2816+
2817+
void do_something_with_node(struct Node *node)
2818+
{
2819+
if(node)
2820+
{
2821+
node->val = nondet_int();
2822+
node->next = nondet_0();
2823+
}
2824+
}
2825+
2826+
Note that no attempt to follow the `next` pointer is made. If an array of
2827+
unknown (or 0) size is encountered, a diagnostic is emitted and the array
2828+
is not further examined.
2829+
2830+
Some care must be taken when choosing the regular expressions for globals and
2831+
functions. Names starting with `__` are reserved for internal purposes; For
2832+
example, replacing functions or setting global variables with the `__CPROVER`
2833+
prefix might make analysis impossible. To avoid doing this by accident, negative
2834+
lookahead can be used. For example, `(?!__).*` matches all names not starting
2835+
with `__`.
2836+
2837+
26822838
\subsection man_instrumentation-api The CPROVER API Reference
26832839

26842840
The following sections summarize the functions available to programs

0 commit comments

Comments
 (0)