@@ -2014,6 +2014,162 @@ Flag | Check
20142014` --uninitialized-check ` | add checks for uninitialized locals (experimental)
20152015` --error-label label ` | check that given label is unreachable
20162016
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+
20172173\subsection man_instrumentation-api The CPROVER API Reference
20182174
20192175The following sections summarize the functions available to programs
0 commit comments