Skip to content

Commit 2e89f66

Browse files
author
Remi Delmas
committed
CONTRACTS: insert reachability canary asssertions
When a GOTO function has no body, insert a canary assertion to make sure the function is indeed unreachable.
1 parent 20535ad commit 2e89f66

File tree

6 files changed

+47
-18
lines changed

6 files changed

+47
-18
lines changed

regression/contracts-dfcc/assigns_replace_02/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ int main()
99
{
1010
int n;
1111
int m = 4;
12-
bar(&n);
12+
foo(&n);
1313
assert(m == 4);
1414

1515
return 0;

src/goto-instrument/contracts/dynamic-frames/dfcc_instrument.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,20 @@ void dfcc_instrumentt::instrument_function_body(
323323

324324
if(!goto_function.body_available())
325325
{
326-
log.warning() << "DFCC instrumentation: '" << function_id
327-
<< "' body is not available. Results may be unsound if the "
328-
"actual function has side effects."
329-
<< messaget::eom;
326+
// we interpret this as "the function should be unreachable"
327+
// create fatal assertion code block as body
328+
const auto &function_location =
329+
utils.get_function_symbol(function_id).location;
330+
source_locationt sl;
331+
sl.set_property_class("reachability");
332+
sl.set_function(function_id);
333+
sl.set_line(0);
334+
sl.set_column(0);
335+
sl.set_file(function_location.get_file());
336+
sl.set_working_directory(function_location.get_working_directory());
337+
sl.set_comment(
338+
"Function " + id2string(function_id) + " should not be reachable");
339+
utils.gen_fatal_assertion_body(function_id, sl);
330340
return;
331341
}
332342

src/goto-instrument/contracts/dynamic-frames/dfcc_library.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,6 @@ void dfcc_libraryt::inhibit_front_end_builtins()
469469
const auto &fid = it.first;
470470
if(goto_model.symbol_table.has_symbol(fid))
471471
{
472-
// make sure parameter symbols exist
473-
utils.fix_parameters_symbols(fid);
474-
475472
// create fatal assertion code block as body
476473
source_locationt sl;
477474
sl.set_function(fid);
@@ -480,16 +477,7 @@ void dfcc_libraryt::inhibit_front_end_builtins()
480477
sl.set_comment(
481478
"Built-in " + id2string(fid) +
482479
" should not be called after contracts transformation");
483-
auto block = create_fatal_assertion(false_exprt(), sl);
484-
auto &symbol = goto_model.symbol_table.get_writeable_ref(fid);
485-
symbol.value = block;
486-
487-
// convert the function
488-
goto_convert(
489-
fid,
490-
goto_model.symbol_table,
491-
goto_model.goto_functions,
492-
message_handler);
480+
utils.gen_fatal_assertion_body(fid, sl);
493481
}
494482
}
495483
}

src/goto-instrument/contracts/dynamic-frames/dfcc_utils.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,28 @@ dfcc_utilst::dfcc_utilst(
4242
{
4343
}
4444

45+
void dfcc_utilst::gen_fatal_assertion_body(
46+
const irep_idt &function_id,
47+
const source_locationt &source_location)
48+
{
49+
PRECONDITION(goto_model.symbol_table.has_symbol(function_id));
50+
51+
// make sure parameter symbols exist
52+
fix_parameters_symbols(function_id);
53+
54+
// create fatal assertion code block as body
55+
auto block = create_fatal_assertion(false_exprt(), source_location);
56+
auto &symbol = goto_model.symbol_table.get_writeable_ref(function_id);
57+
symbol.value = block;
58+
59+
// convert the function
60+
goto_convert(
61+
function_id,
62+
goto_model.symbol_table,
63+
goto_model.goto_functions,
64+
message_handler);
65+
}
66+
4567
const bool dfcc_utilst::symbol_exists(
4668
const irep_idt &name,
4769
const bool require_has_code_type,

src/goto-instrument/contracts/dynamic-frames/dfcc_utils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ class dfcc_utilst
3535
namespacet ns;
3636

3737
public:
38+
/// \brief Genrate a body `assert(false); assume(false);`
39+
/// for the given \p function_id.
40+
/// \param function_id function to generate the body for
41+
/// \param source_location source location to use for the assertion.
42+
/// Must define the property class, comment for the assertion, etc.
43+
void gen_fatal_assertion_body(
44+
const irep_idt &function_id,
45+
const source_locationt &source_location);
46+
3847
/// Returns true iff the given symbol exists and satisfies requirements.
3948
const bool symbol_exists(
4049
const irep_idt &function_id,

src/rel-1.4.1.tar.gz

578 KB
Binary file not shown.

0 commit comments

Comments
 (0)