3838#include < ansi-c/goto-conversion/link_to_library.h>
3939#include < goto-instrument/contracts/cfg_info.h>
4040#include < goto-instrument/contracts/utils.h>
41+ #include < goto-instrument/generate_function_bodies.h>
4142#include < goto-instrument/nondet_static.h>
4243#include < langapi/language.h>
4344#include < langapi/language_file.h>
@@ -257,6 +258,12 @@ void dfcct::partition_function_symbols(
257258 std::set<irep_idt> &contract_symbols,
258259 std::set<irep_idt> &other_symbols)
259260{
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+
260267 // collect contract and other symbols
261268 for (auto &entry : goto_model.symbol_table )
262269 {
@@ -272,7 +279,7 @@ void dfcct::partition_function_symbols(
272279 {
273280 contract_symbols.insert (sym_name);
274281 }
275- else
282+ else if (called_functions. find (sym_name) != called_functions. end ())
276283 {
277284 // it is not a contract
278285 other_symbols.insert (sym_name);
@@ -486,21 +493,6 @@ void dfcct::transform_goto_model()
486493
487494 library.inhibit_front_end_builtins ();
488495
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.
504496 goto_model.goto_functions .update ();
505497
506498 remove_skip (goto_model);
@@ -510,11 +502,25 @@ void dfcct::transform_goto_model()
510502
511503 // This can prune too many functions if function pointers have not been
512504 // 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.
515507 remove_unused_functions (goto_model, message_handler);
516508 goto_model.goto_functions .update ();
517509
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+
518524 reinitialize_model ();
519525}
520526
0 commit comments