Skip to content

Commit b9a5096

Browse files
committed
introduces --havoc-undefined-function
If function body does not exist, we assume that any pointers passed to function may be written to with a non-deterministic value, but only with something the size of the pointer type. regression test for havoc_undefined_functions
1 parent 79defb5 commit b9a5096

File tree

6 files changed

+48
-2
lines changed

6 files changed

+48
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
void function(int *a);
2+
3+
int main()
4+
{
5+
int a=0;
6+
function(&a);
7+
__CPROVER_assert(a==0,"");
8+
return 0;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--havoc-undefined-functions
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$

src/cbmc/cbmc_parse_options.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options)
165165
cmdline.get_value("localize-faults-method"));
166166
}
167167

168+
if(cmdline.isset("havoc-undefined-functions"))
169+
options.set_option("havoc-undefined-functions", true);
170+
168171
if(cmdline.isset("unwind"))
169172
options.set_option("unwind", cmdline.get_value("unwind"));
170173

@@ -995,6 +998,9 @@ void cbmc_parse_optionst::help()
995998
" --partial-loops permit paths with partial loops\n"
996999
" --no-pretty-names do not simplify identifiers\n"
9971000
" --graphml-witness filename write the witness in GraphML format to filename\n" // NOLINT(*)
1001+
" --havoc-undefined-functions\n"
1002+
" for any function that has no body, assign non-deterministic values to\n" // NOLINT(*)
1003+
" any parameters passed as non-const pointers and the return value\n" // NOLINT(*)
9981004
"\n"
9991005
"Backend options:\n"
10001006
" --object-bits n number of bits used for object addresses\n"

src/cbmc/cbmc_parse_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class optionst;
5252
"(show-symbol-table)(show-parse-tree)(show-vcc)" \
5353
"(show-claims)(claim):(show-properties)" \
5454
"(drop-unused-functions)" \
55+
"(havoc-undefined-functions)" \
5556
"(property):(stop-on-fail)(trace)" \
5657
"(error-label):(verbosity):(no-library)" \
5758
"(nondet-static)" \

src/cbmc/symex_bmc.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,13 @@ void symex_bmct::no_body(const irep_idt &identifier)
194194
{
195195
if(body_warnings.insert(identifier).second)
196196
{
197-
warning() <<
198-
"**** WARNING: no body for function " << identifier << eom;
197+
warning() << "**** WARNING: no body for function " << identifier;
198+
199+
if(options.get_bool_option("havoc-undefined-functions"))
200+
{
201+
warning()
202+
<< "; assigning non-deterministic values to any pointer arguments";
203+
}
204+
warning() << eom;
199205
}
200206
}

src/goto-symex/symex_function_call.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Author: Daniel Kroening, [email protected]
2424

2525
#include <util/c_types.h>
2626

27+
#include <pointer-analysis/dereference.h>
28+
2729
#include <analyses/dirty.h>
2830

2931
bool goto_symext::get_unwind_recursion(
@@ -276,6 +278,22 @@ void goto_symext::symex_function_call_code(
276278
symex_assign_rec(state, code);
277279
}
278280

281+
if(options.get_bool_option("havoc-undefined-functions"))
282+
{
283+
// assign non det to function arguments if pointers
284+
// are not const
285+
for(const auto &arg : call.arguments())
286+
{
287+
if(arg.type().id() == ID_pointer &&
288+
!arg.type().subtype().get_bool(ID_C_constant))
289+
{
290+
exprt object = dereference_exprt(arg, arg.type().subtype());
291+
clean_expr(object, state, true);
292+
havoc_rec(state, guardt(), object);
293+
}
294+
}
295+
}
296+
279297
symex_transition(state);
280298
return;
281299
}

0 commit comments

Comments
 (0)