@@ -357,11 +357,25 @@ void bmct::setup()
357
357
setup_unwind ();
358
358
}
359
359
360
- safety_checkert::resultt bmct::execute (const goto_functionst &goto_functions)
360
+ safety_checkert::resultt bmct::execute (
361
+ abstract_goto_modelt &goto_model)
361
362
{
362
363
try
363
364
{
364
- perform_symbolic_execution (goto_functions);
365
+ auto get_goto_function = [&goto_model](const irep_idt &id) ->
366
+ const goto_functionst::goto_functiont &
367
+ {
368
+ return goto_model.get_goto_function (id);
369
+ };
370
+
371
+ perform_symbolic_execution (get_goto_function);
372
+
373
+ // Borrow a reference to the goto functions map. This reference, or
374
+ // iterators pointing into it, must not be stored by this function or its
375
+ // callees, as goto_model.get_goto_function (as used by symex)
376
+ // will have side-effects on it.
377
+ const goto_functionst &goto_functions =
378
+ goto_model.get_goto_functions ();
365
379
366
380
// add a partial ordering, if required
367
381
if (equation.has_threads ())
@@ -492,11 +506,11 @@ void bmct::slice()
492
506
}
493
507
494
508
safety_checkert::resultt bmct::run (
495
- const goto_functionst &goto_functions )
509
+ abstract_goto_modelt &goto_model )
496
510
{
497
511
setup ();
498
512
499
- return execute (goto_functions );
513
+ return execute (goto_model );
500
514
}
501
515
502
516
safety_checkert::resultt bmct::decide (
@@ -595,29 +609,38 @@ void bmct::setup_unwind()
595
609
symex.set_unwind_limit (options.get_unsigned_int_option (" unwind" ));
596
610
}
597
611
612
+ // / Perform core BMC, using an abstract model to supply GOTO function bodies
613
+ // / (perhaps created on demand).
614
+ // / \param opts: command-line options affecting BMC
615
+ // / \param model: provides goto function bodies and the symbol table, perhaps
616
+ // creating those function bodies on demand.
617
+ // / \param ui: user-interface mode (plain text, XML output, JSON output, ...)
618
+ // / \param message: used for logging
619
+ // / \param frontend_configure_bmc: function provided by the frontend program,
620
+ // / which applies frontend-specific configuration to a bmct before running.
598
621
int bmct::do_language_agnostic_bmc (
599
622
const optionst &opts,
600
- const goto_modelt &goto_model ,
623
+ abstract_goto_modelt &model ,
601
624
const ui_message_handlert::uit &ui,
602
625
messaget &message,
603
- std::function<void (bmct &, const goto_modelt &)> frontend_configure_bmc)
626
+ std::function<void (bmct &, const symbol_tablet &)> frontend_configure_bmc)
604
627
{
628
+ const symbol_tablet &symbol_table = model.get_symbol_table ();
605
629
message_handlert &mh = message.get_message_handler ();
606
630
safety_checkert::resultt result;
607
631
goto_symext::branch_worklistt worklist;
608
632
try
609
633
{
610
634
{
611
- cbmc_solverst solvers (
612
- opts, goto_model.symbol_table , message.get_message_handler ());
635
+ cbmc_solverst solvers (opts, symbol_table, message.get_message_handler ());
613
636
solvers.set_ui (ui);
614
637
std::unique_ptr<cbmc_solverst::solvert> cbmc_solver;
615
638
cbmc_solver = solvers.get_solver ();
616
639
prop_convt &pc = cbmc_solver->prop_conv ();
617
- bmct bmc (opts, goto_model. symbol_table , mh, pc, worklist);
640
+ bmct bmc (opts, symbol_table, mh, pc, worklist);
618
641
bmc.set_ui (ui);
619
- frontend_configure_bmc (bmc, goto_model );
620
- result = bmc.run (goto_model. goto_functions );
642
+ frontend_configure_bmc (bmc, symbol_table );
643
+ result = bmc.run (model );
621
644
}
622
645
INVARIANT (
623
646
opts.get_bool_option (" paths" ) || worklist.empty (),
@@ -646,23 +669,22 @@ int bmct::do_language_agnostic_bmc(
646
669
<< " Starting new path (" << worklist.size ()
647
670
<< " to go)\n "
648
671
<< message.eom ;
649
- cbmc_solverst solvers (
650
- opts, goto_model.symbol_table , message.get_message_handler ());
672
+ cbmc_solverst solvers (opts, symbol_table, message.get_message_handler ());
651
673
solvers.set_ui (ui);
652
674
std::unique_ptr<cbmc_solverst::solvert> cbmc_solver;
653
675
cbmc_solver = solvers.get_solver ();
654
676
prop_convt &pc = cbmc_solver->prop_conv ();
655
677
goto_symext::branch_pointt &resume = worklist.front ();
656
678
path_explorert pe (
657
679
opts,
658
- goto_model. symbol_table ,
680
+ symbol_table,
659
681
mh,
660
682
pc,
661
683
resume.equation ,
662
684
resume.state ,
663
685
worklist);
664
- frontend_configure_bmc (pe, goto_model );
665
- result &= pe.run (goto_model. goto_functions );
686
+ frontend_configure_bmc (pe, symbol_table );
687
+ result &= pe.run (model );
666
688
worklist.pop_front ();
667
689
}
668
690
}
@@ -694,18 +716,19 @@ int bmct::do_language_agnostic_bmc(
694
716
UNREACHABLE;
695
717
}
696
718
697
- void bmct::perform_symbolic_execution (const goto_functionst &goto_functions)
719
+ void bmct::perform_symbolic_execution (
720
+ goto_symext::get_goto_functiont get_goto_function)
698
721
{
699
- symex.symex_from_entry_point_of (goto_functions , symex_symbol_table);
722
+ symex.symex_from_entry_point_of (get_goto_function , symex_symbol_table);
700
723
INVARIANT (
701
724
options.get_bool_option (" paths" ) || branch_worklist.empty (),
702
725
" Branch points were saved even though we should have been "
703
726
" executing the entire program and merging paths" );
704
727
}
705
728
706
729
void path_explorert::perform_symbolic_execution (
707
- const goto_functionst &goto_functions )
730
+ goto_symext::get_goto_functiont get_goto_function )
708
731
{
709
732
symex.resume_symex_from_saved_state (
710
- goto_functions , saved_state, &equation, symex_symbol_table);
733
+ get_goto_function , saved_state, &equation, symex_symbol_table);
711
734
}
0 commit comments