38
38
#include < ansi-c/goto-conversion/link_to_library.h>
39
39
#include < goto-instrument/contracts/cfg_info.h>
40
40
#include < goto-instrument/contracts/utils.h>
41
+ #include < goto-instrument/generate_function_bodies.h>
41
42
#include < goto-instrument/nondet_static.h>
42
43
#include < langapi/language.h>
43
44
#include < langapi/language_file.h>
@@ -257,6 +258,12 @@ void dfcct::partition_function_symbols(
257
258
std::set<irep_idt> &contract_symbols,
258
259
std::set<irep_idt> &other_symbols)
259
260
{
261
+ std::set<irep_idt> called_functions;
262
+ find_used_functions (
263
+ goto_functionst::entry_point (),
264
+ goto_model.goto_functions ,
265
+ called_functions);
266
+
260
267
// collect contract and other symbols
261
268
for (auto &entry : goto_model.symbol_table )
262
269
{
@@ -272,7 +279,7 @@ void dfcct::partition_function_symbols(
272
279
{
273
280
contract_symbols.insert (sym_name);
274
281
}
275
- else
282
+ else if (called_functions. find (sym_name) != called_functions. end ())
276
283
{
277
284
// it is not a contract
278
285
other_symbols.insert (sym_name);
@@ -486,21 +493,6 @@ void dfcct::transform_goto_model()
486
493
487
494
library.inhibit_front_end_builtins ();
488
495
489
- // TODO implement a means to inhibit unreachable functions (possibly via the
490
- // code that implements drop-unused-functions followed by
491
- // generate-function-bodies):
492
- // Traverse the call tree from the given entry point to identify
493
- // functions symbols that are effectively called in the model,
494
- // Then goes over all functions of the model and turns the bodies of all
495
- // functions that are not in the used function set into:
496
- // ```c
497
- // assert(false, "function identified as unreachable");
498
- // assume(false);
499
- // ```
500
- // That way, if the analysis mistakenly pruned some functions, assertions
501
- // will be violated and the analysis will fail.
502
- // TODO: add a command line flag to tell the instrumentation to not prune
503
- // a function.
504
496
goto_model.goto_functions .update ();
505
497
506
498
remove_skip (goto_model);
@@ -510,11 +502,25 @@ void dfcct::transform_goto_model()
510
502
511
503
// This can prune too many functions if function pointers have not been
512
504
// yet been removed or if the entry point is not defined.
513
- // Another solution would be to rewrite the bodies of functions that seem to
514
- // be unreachable into assert(false);assume(false)
505
+ // TODO: add a command line flag to tell the instrumentation to not prune
506
+ // a function.
515
507
remove_unused_functions (goto_model, message_handler);
516
508
goto_model.goto_functions .update ();
517
509
510
+ // generate assert(0); assume(0); function bodies for all functions missing an
511
+ // implementation (other than ones containing __CPROVER in their name)
512
+ auto generate_implementation = generate_function_bodies_factory (
513
+ " assert-false-assume-false" ,
514
+ c_object_factory_parameterst{},
515
+ goto_model.symbol_table ,
516
+ message_handler);
517
+ generate_function_bodies (
518
+ std::regex (" (?!" CPROVER_PREFIX " ).*" ),
519
+ *generate_implementation,
520
+ goto_model,
521
+ message_handler);
522
+ goto_model.goto_functions .update ();
523
+
518
524
reinitialize_model ();
519
525
}
520
526
0 commit comments