@@ -2014,6 +2014,162 @@ Flag | Check
2014
2014
` --uninitialized-check ` | add checks for uninitialized locals (experimental)
2015
2015
` --error-label label ` | check that given label is unreachable
2016
2016
2017
+ #### Generating/Replacing function bodies
2018
+
2019
+ Sometimes implementations for called functions are not available in the goto
2020
+ program, or it is desirable to replace bodies of functions with certain
2021
+ predetermined stubs (for example to confirm that these functions are never
2022
+ called, or to indicate that these functions will never return). For this purpose
2023
+ goto-instrument provides the ` --generate-function-body ` and
2024
+ ` --replace-function-body ` options, that take a regular expression (in
2025
+ [ ECMAScript syntax] ( http://en.cppreference.com/w/cpp/regex/ecmascript ) ) that
2026
+ describes the names of the functions to generate or replace, the difference
2027
+ being that ` --generate-function-body ` will only generate bodies of functions
2028
+ that do not already have one, whereas ` --replace-function-body ` will do this and
2029
+ in addition also replace existing bodies of functions with the stub.
2030
+
2031
+ The shape of the stub itself can be chosen with the ` --replace-function-body-options `
2032
+ parameter, which can take the following values:
2033
+
2034
+ Option | Result
2035
+ -----------------------------|-------------------------------------------------------------
2036
+ ` nondet-return ` | Do nothing and return a nondet result (this is the default)
2037
+ ` empty ` | Delete the body of the function
2038
+ ` assert-false ` | Make the body contain an assert(false)
2039
+ ` assume-false ` | Make the body contain an assume(false)
2040
+ ` assert-false-assume-false ` | Combines assert-false and assume-false
2041
+ ` havoc ` | Set the contents of parameters and globals to nondet
2042
+
2043
+ The various combinations of assert-false and assume-false can be used to
2044
+ indicate that functions shouldn't be called, that they will never return or
2045
+ both.
2046
+
2047
+ Example: We have a program like this:
2048
+
2049
+ // error_example.c
2050
+ #include <stdlib.h>
2051
+
2052
+ void api_error(void);
2053
+ void internal_error(void);
2054
+
2055
+ int main(void)
2056
+ {
2057
+ int arr[ 10] = {1,2,3,4,5, 6, 7, 8, 9, 10};
2058
+ int sum = 0;
2059
+ for(int i = 1; i < 10; ++i)
2060
+ {
2061
+ sum += arr[ i] ;
2062
+ }
2063
+ if(sum != 55)
2064
+ {
2065
+ // we made a mistake when calculating the sum
2066
+ internal_error();
2067
+ }
2068
+ if(rand() < 0)
2069
+ {
2070
+ // we think this cannot happen
2071
+ api_error();
2072
+ }
2073
+ return 0;
2074
+ }
2075
+
2076
+ Now, we can compile the program and detect that the error functions are indeed
2077
+ called by invoking these commands
2078
+
2079
+ goto-cc error_example.c -o error_example.goto
2080
+ # Replace all functions ending with _error
2081
+ # (Excluding those starting with __)
2082
+ # With ones that have an assert(false) body
2083
+ goto-instrument error_example.goto error_example_replaced.goto \
2084
+ --replace-function-body '(?!__).*_error' \
2085
+ --replace-function-body-options assert-false
2086
+ cbmc error_example_replaced.goto
2087
+
2088
+ Which gets us the output
2089
+
2090
+ > ** Results:
2091
+ > [ internal_error.assertion.1] assertion false: FAILURE
2092
+ > [ api_error.assertion.1] assertion false: FAILURE
2093
+ >
2094
+ >
2095
+ > ** 2 of 2 failed (2 iterations)
2096
+ > VERIFICATION FAILED
2097
+
2098
+ As opposed to the verification success we would have gotten without the
2099
+ replacement
2100
+
2101
+
2102
+ The havoc option takes further parameters ` globals ` and ` params ` with this
2103
+ syntax: ` havoc[,globals:<regex>][,params:<regex>] ` (where the square brackets
2104
+ indicate an optional part). The regular expressions have the same format as the
2105
+ those for the ` --replace-function-body ` and ` --generate-function-body ` options
2106
+ and indicate which globals and function parameters should be set to nondet. All
2107
+ regular expressions require exact matches (i.e. the regular expression ` ab? `
2108
+ will match 'a' and 'b' but not 'adrian' or 'bertha').
2109
+
2110
+ Example: With a C program like this
2111
+
2112
+ struct Complex {
2113
+ double real;
2114
+ double imag;
2115
+ };
2116
+
2117
+ struct Complex AGlobalComplex;
2118
+ int do_something_with_complex(struct Complex *complex);
2119
+
2120
+ And the command line
2121
+
2122
+ goto-instrument in.goto out.goto
2123
+ --replace-function-body do_something_with_complex
2124
+ --replace-function-body-options
2125
+ 'havoc,params:.*,globals:AGlobalComplex'
2126
+
2127
+ The goto code equivalent of the following will be generated:
2128
+
2129
+ int do_something_with_complex(struct Complex *complex)
2130
+ {
2131
+ if(complex)
2132
+ {
2133
+ complex->real = nondet_double();
2134
+ complex->imag = nondet_double();
2135
+ }
2136
+ return nondet_int();
2137
+ }
2138
+
2139
+ A note on limitations: Because only static information is used for code
2140
+ generation, arrays of unknown size and pointers will not be affected by this;
2141
+ Which means that for code like this:
2142
+
2143
+ struct Node {
2144
+ int val;
2145
+ struct Node *next;
2146
+ };
2147
+
2148
+ void do_something_with_node(struct Node *node);
2149
+
2150
+ Code like this will be generated:
2151
+
2152
+ void do_something_with_node(struct Node *node)
2153
+ {
2154
+ if(node)
2155
+ {
2156
+ node->val = nondet_int();
2157
+ node->next = nondet_0();
2158
+ }
2159
+ }
2160
+
2161
+ Note that no attempt to follow the ` next ` pointer is made. If an array of
2162
+ unknown (or 0) size is encountered, a diagnostic is emitted and the array
2163
+ is not further examined.
2164
+
2165
+ Some care must be taken when choosing the regular expressions for globals and
2166
+ functions. Names starting with ` __ ` are reserved for internal purposes; For
2167
+ example, replacing functions or setting global variables with the ` __CPROVER `
2168
+ prefix might make analysis impossible. To avoid doing this by accident, negative
2169
+ lookahead can be used. For example, ` (?!__).* ` matches all names not starting
2170
+ with ` __ ` .
2171
+
2172
+
2017
2173
\subsection man_instrumentation-api The CPROVER API Reference
2018
2174
2019
2175
The following sections summarize the functions available to programs
0 commit comments