CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
symex_bmc_incremental_one_loop.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Incremental Bounded Model Checking for ANSI-C
4
5Author: Peter Schrammel, Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include <limits>
10
12
14
16
18 message_handlert &message_handler,
19 const symbol_tablet &outer_symbol_table,
21 const optionst &options,
22 path_storaget &path_storage,
23 guard_managert &guard_manager,
24 unwindsett &unwindset,
26 : symex_bmct(
27 message_handler,
28 outer_symbol_table,
29 target,
30 options,
31 path_storage,
32 guard_manager,
33 unwindset),
34 incr_loop_id(options.get_option("incremental-loop")),
35 incr_max_unwind(
36 options.is_set("unwind-max") ? options.get_signed_int_option("unwind-max")
37 : std::numeric_limits<unsigned>::max()),
38 incr_min_unwind(
39 options.is_set("unwind-min") ? options.get_signed_int_option("unwind-min")
40 : 0),
41 output_ui(output_ui)
42{
43 // the intended behaviour is to stop asserts that are violated before the
44 // unwind
45 // therefore if the min-unwind is 1, then we do one unwind and immediately
46 // start checking for properties
48 incr_min_unwind > 1 &&
49 options.get_bool_option("ignore-properties-before-unwind-min");
50}
51
53 const symex_targett::sourcet &source,
54 const call_stackt &context,
55 unsigned unwind)
56{
57 const irep_idt id = goto_programt::loop_id(source.function_id, *source.pc);
58
60 unsigned this_loop_limit = std::numeric_limits<unsigned>::max();
61
62 // use the incremental limits if it is the specified incremental loop
63 if(id == incr_loop_id)
64 {
66 if(unwind + 1 >= incr_min_unwind)
67 ignore_assertions = false;
68
70 }
71 else
72 {
74 {
76 handler(context, source.pc->loop_number, unwind, this_loop_limit);
77 if(abort_unwind_decision.is_known())
78 break;
79 }
80
81 // If no handler gave an opinion, use standard command-line --unwindset
82 // / --unwind options to decide:
83 if(abort_unwind_decision.is_unknown())
84 {
85 auto limit = unwindset.get_limit(id, source.thread_nr);
86
87 if(!limit.has_value())
89 else
90 abort_unwind_decision = tvt(unwind >= *limit);
91 }
92 }
93
95 abort_unwind_decision.is_known(), "unwind decision should be taken by now");
96 bool abort = abort_unwind_decision.is_true();
97
98 log_unwinding(unwind);
99 log.statistics() << (abort ? "Not unwinding" : "Unwinding") << " loop " << id
100 << " iteration " << unwind;
101
102 if(this_loop_limit != std::numeric_limits<unsigned>::max())
103 log.statistics() << " (" << this_loop_limit << " max)";
104
105 log.statistics() << " " << source.pc->source_location() << " thread "
106 << source.thread_nr << log.eom;
107
108 return abort;
109}
110
115 const irep_idt &loop_id,
116 unsigned unwind)
117{
118 if(unwind < incr_min_unwind)
119 return false;
120
121 // loop specified by incremental-loop
122 return (loop_id == incr_loop_id);
123}
124
126 const get_goto_functiont &get_goto_function,
127 symbol_tablet &new_symbol_table)
128{
130
131 new_symbol_table = symex_with_state(*state, get_goto_function);
132
133 return should_pause_symex;
134}
135
137 const get_goto_functiont &get_goto_function)
138{
139 should_pause_symex = false;
140
142
143 return should_pause_symex;
144}
146{
147 structured_datat data{{{labelt({"current", "unwinding"}),
149 json_numbert{std::to_string(unwind)})}}};
150 log.statistics() << data;
151}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
static irep_idt loop_id(const irep_idt &function_id, const instructiont &instruction)
Human-readable loop name.
virtual symbol_tablet symex_with_state(statet &state, const get_goto_functiont &get_goto_functions)
Symbolically execute the entire program starting from entry point.
bool ignore_assertions
If this flag is set to true then assertions will be temporarily ignored by the symbolic executions.
Definition goto_symex.h:171
static get_goto_functiont get_goto_function(abstract_goto_modelt &goto_model)
Return a function to get/load a goto function from the given goto model Create a default delegate to ...
std::unique_ptr< statet > initialize_entry_point_state(const get_goto_functiont &get_goto_function)
Initialize the symbolic execution and the given state with the beginning of the entry point function.
std::function< const goto_functionst::goto_functiont &(const irep_idt &)> get_goto_functiont
The type of delegate functions that retrieve a goto_functiont for a particular function identifier.
Definition goto_symex.h:93
messaget log
The messaget to write log messages to.
Definition goto_symex.h:278
bool should_pause_symex
Set when states are pushed onto the workqueue If this flag is set at the end of a symbolic execution ...
Definition goto_symex.h:167
mstreamt & statistics() const
Definition message.h:411
static eomt eom
Definition message.h:289
bool get_bool_option(const std::string &option) const
Definition options.cpp:44
Storage for symbolic execution paths to be resumed later.
A way of representing nested key/value data.
The symbol table.
bool resume(const get_goto_functiont &get_goto_function)
Return true if symex can be resumed.
symex_bmc_incremental_one_loopt(message_handlert &, const symbol_tablet &outer_symbol_table, symex_target_equationt &, const optionst &, path_storaget &, guard_managert &, unwindsett &, ui_message_handlert::uit output_ui)
bool from_entry_point_of(const get_goto_functiont &get_goto_function, symbol_tablet &new_symbol_table)
Return true if symex can be resumed.
bool check_break(const irep_idt &loop_id, unsigned unwind) override
Defines condition for interrupting symbolic execution for incremental BMC.
std::unique_ptr< goto_symext::statet > state
bool should_stop_unwind(const symex_targett::sourcet &source, const call_stackt &context, unsigned unwind) override
Determine whether to unwind a loop.
std::vector< loop_unwind_handlert > loop_unwind_handlers
Callbacks that may provide an unwind/do-not-unwind decision for a loop.
Definition symex_bmc.h:88
unwindsett & unwindset
Definition symex_bmc.h:84
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
Definition threeval.h:20
std::optional< unsigned > get_limit(const irep_idt &loop, unsigned thread_id) const
STL namespace.
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
void abort(void)
Definition stdlib.c:128
This is unused by this implementation of guards, but can be used by other implementations of the same...
Definition guard_expr.h:20
static structured_data_entryt data_node(const jsont &data)
Identifies source in the context of symbolic execution.
goto_programt::const_targett pc
Loop unwinding.