Skip to content

Commit 9f1f3f5

Browse files
authored
Merge pull request #3457 from danpoe/feature/nondet-return-values
Generate function bodies with nondet return values
2 parents 18cb59a + 5fa9452 commit 9f1f3f5

File tree

9 files changed

+132
-2
lines changed

9 files changed

+132
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <assert.h>
2+
3+
const int func();
4+
5+
void main()
6+
{
7+
assert(func() == 0);
8+
assert(func() != 0);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--generate-function-body func --generate-function-body-options nondet-return
4+
^SIGNAL=0$
5+
\[main.assertion.1\] line \d+ assertion func\(\) == 0: FAILURE
6+
\[main.assertion.2\] line \d+ assertion func\(\) != 0: FAILURE
7+
--
8+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
int **func();
5+
6+
void main()
7+
{
8+
int **p = func();
9+
10+
assert(p != NULL);
11+
assert(*p != NULL);
12+
13+
assert(**p == 0);
14+
assert(**p != 0);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--generate-function-body func --generate-function-body-options nondet-return --min-null-tree-depth 10 --max-nondet-tree-depth 5
4+
^SIGNAL=0$
5+
\[main.assertion.1\] line \d+ assertion p != .*(0|(NULL))\)?: SUCCESS
6+
\[main.assertion.2\] line \d+ assertion \*p != .*(0|(NULL))\)?: SUCCESS
7+
\[main.assertion.3\] line \d+ assertion \*\*p == 0: FAILURE
8+
\[main.assertion.4\] line \d+ assertion \*\*p != 0: FAILURE
9+
--
10+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <assert.h>
2+
3+
int func();
4+
5+
void main()
6+
{
7+
assert(func() == 0);
8+
assert(func() != 0);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--generate-function-body func --generate-function-body-options nondet-return
4+
^SIGNAL=0$
5+
\[main.assertion.1\] line \d+ assertion func\(\) == 0: FAILURE
6+
\[main.assertion.2\] line \d+ assertion func\(\) != 0: FAILURE
7+
--
8+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
typedef struct st
5+
{
6+
struct st *next;
7+
int data;
8+
} st_t;
9+
10+
st_t dummy;
11+
12+
st_t *func();
13+
14+
void main()
15+
{
16+
st_t *st = func();
17+
18+
assert(st != NULL);
19+
20+
assert(st->next != NULL);
21+
assert(st->next->next != NULL);
22+
assert(st->next->next->next == NULL);
23+
24+
assert(st != &dummy);
25+
assert(st->next != &dummy);
26+
assert(st->next->next != &dummy);
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--generate-function-body func --generate-function-body-options nondet-return --min-null-tree-depth 10 --max-nondet-tree-depth 3
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
VERIFICATION SUCCESSFUL
7+
--
8+
^warning: ignoring

src/goto-instrument/generate_function_bodies.cpp

+38-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Diffblue Ltd.
1616

1717
#include <util/arith_tools.h>
1818
#include <util/format_expr.h>
19+
#include <util/fresh_symbol.h>
1920
#include <util/make_unique.h>
2021
#include <util/string_utils.h>
2122

@@ -271,11 +272,46 @@ class havoc_generate_function_bodiest : public generate_function_bodiest
271272

272273
if(function.type.return_type() != void_typet())
273274
{
275+
typet type(function.type.return_type());
276+
type.remove(ID_C_constant);
277+
278+
symbolt &aux_symbol = get_fresh_aux_symbol(
279+
type,
280+
id2string(function_name),
281+
"return_value",
282+
function_symbol.location,
283+
ID_C,
284+
symbol_table);
285+
286+
aux_symbol.is_static_lifetime = false;
287+
288+
auto decl_instruction = add_instruction();
289+
decl_instruction->make_decl();
290+
decl_instruction->code = code_declt(aux_symbol.symbol_expr());
291+
292+
goto_programt dest;
293+
294+
havoc_expr_rec(
295+
aux_symbol.symbol_expr(),
296+
0,
297+
function_symbol.location,
298+
symbol_table,
299+
dest);
300+
301+
function.body.destructive_append(dest);
302+
303+
exprt return_expr = typecast_exprt::conditional_cast(
304+
aux_symbol.symbol_expr(), function.type.return_type());
305+
274306
auto return_instruction = add_instruction();
275307
return_instruction->make_return();
276-
return_instruction->code = code_returnt(side_effect_expr_nondett(
277-
function.type.return_type(), function_symbol.location));
308+
return_instruction->code = code_returnt(return_expr);
309+
310+
auto dead_instruction = add_instruction();
311+
dead_instruction->make_dead();
312+
dead_instruction->code = code_deadt(aux_symbol.symbol_expr());
278313
}
314+
279315
auto end_function_instruction = add_instruction();
280316
end_function_instruction->make_end_function();
281317

0 commit comments

Comments
 (0)