Skip to content

Commit 7e3dee3

Browse files
authored
Merge pull request diffblue#381 from diffblue/smowton/merge/develop-2018-04-19
Smowton/merge/develop 2018 04 19
2 parents 7142524 + 7a88c2c commit 7e3dee3

File tree

239 files changed

+4316
-1175
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

239 files changed

+4316
-1175
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
3535
# Ensure NDEBUG is not set for release builds
3636
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
3737
# Enable lots of warnings
38-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror")
38+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror -Wno-deprecated-declarations")
3939
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
4040
# This would be the place to enable warnings for Windows builds, although
4141
# config.inc doesn't seem to do that currently

cbmc/CHANGELOG

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
5.9
2+
===
3+
* GOTO-INSTRUMENT: --generate-function-body can be used to
4+
generate bodies for functions that don't have a body
5+
in the goto code. This supercedes the functionality
6+
of --undefined-function-is-assume-false
7+
18
5.8
29
===
310

cbmc/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
2525
# Ensure NDEBUG is not set for release builds
2626
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
2727
# Enable lots of warnings
28-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror")
28+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror -Wno-deprecated-declarations")
2929
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
3030
# This would be the place to enable warnings for Windows builds, although
3131
# config.inc doesn't seem to do that currently
@@ -78,7 +78,6 @@ set_target_properties(
7878
mmcc
7979
pointer-analysis
8080
solvers
81-
string_utils
8281
test-bigint
8382
testing-utils
8483
unit

cbmc/doc/cbmc-user-manual.md

+158
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,164 @@ Flag | Check
20142014
`--uninitialized-check` | add checks for uninitialized locals (experimental)
20152015
`--error-label label` | check that given label is unreachable
20162016

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+
20172175
\subsection man_instrumentation-api The CPROVER API Reference
20182176

20192177
The following sections summarize the functions available to programs
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@interface ClassAnnotation {
2+
}
3+
4+
@interface MethodAnnotation {
5+
}
6+
7+
@interface FieldAnnotation {
8+
}
9+
10+
@ClassAnnotation
11+
public class annotations
12+
{
13+
@FieldAnnotation
14+
public int x;
15+
16+
@FieldAnnotation
17+
public static int y;
18+
19+
@MethodAnnotation
20+
public void main()
21+
{
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
annotations.class
3+
--verbosity 10 --show-symbol-table
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^Type\.\.\.\.\.\.\.\.: @java::ClassAnnotation struct annotations
7+
^Type\.\.\.\.\.\.\.\.: @java::MethodAnnotation \(struct annotations \*\) -> void$
8+
^Type\.\.\.\.\.\.\.\.: @java::FieldAnnotation int$
9+
--
10+
--
11+
The purpose of the test is ensuring that annotations can be shown in the symbol
12+
table.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public class Test {
2+
public void main() {}
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE symex-driven-lazy-loading-expected-failure
2+
Test.class
3+
--classpath ./NotHere.jar
4+
^EXIT=6$
5+
^SIGNAL=0$
6+
^the program has no entry point$
7+
^failed to load class `Test'$
8+
--
9+
--
10+
symex-driven lazy loading should emit "the program has no entry point" but currently doesn't
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE symex-driven-lazy-loading-expected-failure
2+
Test.class
3+
--classpath ./NotHere
4+
^EXIT=6$
5+
^SIGNAL=0$
6+
^the program has no entry point$
7+
^failed to load class `Test'$
8+
--
9+
--
10+
symex-driven lazy loading should emit "the program has no entry point" but currently doesn't
583 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public class Test
2+
{
3+
public int x;
4+
5+
public static void main(String[] args)
6+
{
7+
assert(false);
8+
}
9+
10+
public static void notOverlain()
11+
{
12+
assert(true);
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.diffblue;
2+
3+
public @interface OverlayClassImplementation {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.diffblue;
2+
3+
public @interface OverlayMethodImplementation {
4+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import com.diffblue.OverlayClassImplementation;
2+
import com.diffblue.OverlayMethodImplementation;
3+
4+
@OverlayClassImplementation
5+
public class Test
6+
{
7+
public int x;
8+
9+
@OverlayMethodImplementation
10+
public static void main(String[] args)
11+
{
12+
assert(true);
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
Test.class
3+
--classpath `./format_classpath.sh . annotations correct-overlay` --verbosity 10
4+
^Getting class `Test' from file \.[\\/]Test\.class$
5+
^Getting class `Test' from file correct-overlay[\\/]Test\.class$
6+
^Adding symbol from overlay class: field 'x'$
7+
^Adding symbol from overlay class: method 'java::Test\.<init>:\(\)V'$
8+
^Field definition for java::Test\.x already loaded from overlay class$
9+
^Adding symbol from overlay class: method 'java::Test\.main:\(\[Ljava/lang/String;\)V'$
10+
^Method java::Test\.<init>:\(\)V exists in an overlay class without being marked as an overlay and also exists in the underlying class
11+
^Adding symbol: method 'java::Test\.notOverlain:\(\)V'$
12+
^VERIFICATION SUCCESSFUL$
13+
^EXIT=0$
14+
^SIGNAL=0$
15+
--
16+
^Skipping class Test marked with OverlayClassImplementation but found before original definition$
17+
^Skipping duplicate definition of class Test not marked with OverlayClassImplementation$
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
Test.class
3+
--classpath `./format_classpath.sh . annotations . correct-overlay` --verbosity 10
4+
^Getting class `Test' from file \.[\\/]Test\.class$
5+
^Getting class `Test' from file correct-overlay[\\/]Test\.class$
6+
^Skipping duplicate definition of class Test not marked with OverlayClassImplementation$
7+
^Adding symbol from overlay class: field 'x'$
8+
^Adding symbol from overlay class: method 'java::Test\.<init>:\(\)V'$
9+
^Field definition for java::Test\.x already loaded from overlay class$
10+
^Adding symbol from overlay class: method 'java::Test\.main:\(\[Ljava/lang/String;\)V'$
11+
^Method java::Test\.<init>:\(\)V exists in an overlay class without being marked as an overlay and also exists in the underlying class
12+
^Adding symbol: method 'java::Test\.notOverlain:\(\)V'$
13+
^VERIFICATION SUCCESSFUL$
14+
^EXIT=0$
15+
^SIGNAL=0$
16+
--
17+
^Skipping class Test marked with OverlayClassImplementation but found before original definition$
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
3+
unameOut="$(uname -s)"
4+
case "${unameOut}" in
5+
CYGWIN*) separator=";";;
6+
MINGW*) separator=";";;
7+
MSYS*) separator=";";;
8+
Windows*) separator=";";;
9+
*) separator=":"
10+
esac
11+
12+
echo -n `IFS=$separator; echo "$*"`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CORE
2+
Test.class
3+
--classpath `./format_classpath.sh annotations correct-overlay .` --verbosity 10
4+
^Getting class `Test' from file correct-overlay[\\/]Test\.class$
5+
^Getting class `Test' from file \.[\\/]Test\.class$
6+
^Skipping class Test marked with OverlayClassImplementation but found before original definition$
7+
^Adding symbol: field 'x'$
8+
^Adding symbol: method 'java::Test\.main:\(\[Ljava/lang/String;\)V'$
9+
^Adding symbol: method 'java::Test\.notOverlain:\(\)V'$
10+
^VERIFICATION FAILED$
11+
^EXIT=10$
12+
^SIGNAL=0$
13+
--
14+
^Skipping duplicate definition of class Test not marked with OverlayClassImplementation$
15+
^Adding symbol from overlay class
16+
exists in an overlay class without being marked as an overlay and also exists in the underlying class
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import com.diffblue.OverlayClassImplementation;
2+
import com.diffblue.OverlayMethodImplementation;
3+
4+
public class Test
5+
{
6+
@OverlayMethodImplementation
7+
public static void main(String[] args)
8+
{
9+
assert(false);
10+
}
11+
}

0 commit comments

Comments
 (0)