@@ -2014,6 +2014,164 @@ 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 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 ` option, that takes a
2024
+ regular expression (in [ ECMAScript syntax]
2025
+ (http://en.cppreference.com/w/cpp/regex/ecmascript )) that describes the names of
2026
+ the functions to generate. Note that this will only generate bodies for
2027
+ functions that do not already have one; If one wishes to replace the body of a
2028
+ function with an existing definition, the ` --remove-function-body ` option can be
2029
+ used to remove the body of the function prior to generating a new one.
2030
+
2031
+ The shape of the stub itself can be chosen with the
2032
+ ` --generate-function-body-options ` parameter, which can take the following
2033
+ values:
2034
+
2035
+ Option | Result
2036
+ -----------------------------|-------------------------------------------------------------
2037
+ ` nondet-return ` | Do nothing and return a nondet result (this is the default)
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
+ --generate-function-body '(?!__).*_error' \
2085
+ --generate-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
+ generation.
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 ` --generate-function-body ` option and indicate which globals and
2106
+ function parameters should be set to nondet. All regular expressions require
2107
+ exact matches (i.e. the regular expression ` a|b ` will match 'a' and 'b' but not
2108
+ '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
+ --generate-function-body do_something_with_complex
2124
+ --generate-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
+ AGlobalComplex.real = nondet_double();
2137
+ AGlobalComplex.imag = nondet_double();
2138
+ return nondet_int();
2139
+ }
2140
+
2141
+ A note on limitations: Because only static information is used for code
2142
+ generation, arrays of unknown size and pointers will not be affected by this;
2143
+ Which means that for code like this:
2144
+
2145
+ struct Node {
2146
+ int val;
2147
+ struct Node *next;
2148
+ };
2149
+
2150
+ void do_something_with_node(struct Node *node);
2151
+
2152
+ Code like this will be generated:
2153
+
2154
+ void do_something_with_node(struct Node *node)
2155
+ {
2156
+ if(node)
2157
+ {
2158
+ node->val = nondet_int();
2159
+ node->next = nondet_0();
2160
+ }
2161
+ }
2162
+
2163
+ Note that no attempt to follow the ` next ` pointer is made. If an array of
2164
+ unknown (or 0) size is encountered, a diagnostic is emitted and the array is not
2165
+ further examined.
2166
+
2167
+ Some care must be taken when choosing the regular expressions for globals and
2168
+ functions. Names starting with ` __ ` are reserved for internal purposes; For
2169
+ example, replacing functions or setting global variables with the ` __CPROVER `
2170
+ prefix might make analysis impossible. To avoid doing this by accident, negative
2171
+ lookahead can be used. For example, ` (?!__).* ` matches all names not starting
2172
+ with ` __ ` .
2173
+
2174
+
2017
2175
\subsection man_instrumentation-api The CPROVER API Reference
2018
2176
2019
2177
The following sections summarize the functions available to programs
0 commit comments