1/*******************************************************************\
3Module: Abstract Interpretation
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
45#ifndef CPROVER_ANALYSES_AI_H
46#define CPROVER_ANALYSES_AI_H
127 std::unique_ptr<ai_history_factory_baset> &&
hf,
128 std::unique_ptr<ai_domain_factory_baset> &&
df,
129 std::unique_ptr<ai_storage_baset> &&st,
152 fixedpoint(p, function_id, goto_program, goto_functions, ns);
189 fixedpoint(p, function_id, goto_function.body, goto_functions, ns);
212 INVARIANT(!l->is_end_function(),
"No state after the last instruction");
213 return storage->abstract_traces_before(std::next(l));
242 INVARIANT(!l->is_end_function(),
"No state after the last instruction");
255 INVARIANT(!l->is_end_function(),
"No state after the last instruction");
261 *(
storage->abstract_traces_before(
n)),
263 // Caller history not needed as this is a local step
284 std::ostream &out)
const;
312 std::ostream &out)
const;
317 std::ostream &out)
const
327 std::ostream &out)
const
454 // function calls and return are special cases
455 // different kinds of analysis handle these differently so these are virtual
456 // visit_function_call handles which function(s) to call,
457 // while visit_edge_function_call handles a single call
474 // The most basic step, computing one edge / transformer application.
514 // Domain and history storage
528// Perform interprocedural analysis by simply recursing in the interpreter
529// This can lead to a call stack overflow if the domain has a large height
534 std::unique_ptr<ai_history_factory_baset> &&
hf,
535 std::unique_ptr<ai_domain_factory_baset> &&
df,
536 std::unique_ptr<ai_storage_baset> &&st,
543 // Override the function that handles a single function call edge
564template <
typename domainT>
579 explicit ait(std::unique_ptr<ai_domain_factory_baset> &&
df)
592 // The older interface for non-modifying access
593 // Not recommended as it will throw an exception if a location has not
594 // been reached in an analysis and there is no (other) way of telling
595 // if a location has been reached.
596 DEPRECATED(
SINCE(2019, 08, 01,
"use abstract_state_{before,after} instead"))
601 if(p.use_count() == 1)
603 // Would be unsafe to return the dereferenced object
604 throw std::out_of_range(
"failed to find state");
607 return static_cast<const domainT &
>(*p);
611 // Support the legacy get_state interface which is needed for a few domains
612 // This is one of the few users of the legacy get_state(locationt) method
613 // in location_sensitive_storaget.
628 // To keep the old constructor interface we disable logging
653template<
typename domainT>
677 static_cast<const domainT &
>(src), from, to, ns);
692 // construct an initial shared state collecting the results of all
695 tmp.add_instruction();
725 if(is_threaded(
t_it))
731 gf_entry.second.body.instructions.end();
739 // now feed in the shared state into all concurrently executing
740 // functions, and iterate until the shared state stabilizes
769 // the underlying domain must make sure that the final state
770 // carries all possible values; otherwise we would need to
771 // merge over each and every state
772 if(l->is_end_function())
780#endif // CPROVER_ANALYSES_AI_H
Abstract Interpretation Domain.
Abstract Interpretation history.
Abstract Interpretation Storage.
Abstract interface to eager or lazy GOTO models.
virtual const symbol_tablet & get_symbol_table() const =0
Accessor to get the symbol table.
virtual const goto_functionst & get_goto_functions() const =0
Accessor to get a raw goto_functionst.
The common case of history is to only care about where you are now, not how you got there!...
This is the basic interface of the abstract interpreter with default implementations of the core func...
virtual cstate_ptrt abstract_state_after(const trace_ptrt &p) const
xmlt output_xml(const namespacet &ns, const goto_functionst::goto_functiont &goto_function) const
Output the abstract states for a single function as XML.
goto_programt::const_targett locationt
ai_baset(std::unique_ptr< ai_history_factory_baset > &&hf, std::unique_ptr< ai_domain_factory_baset > &&df, std::unique_ptr< ai_storage_baset > &&st, message_handlert &mh)
void operator()(const goto_functionst &goto_functions, const namespacet &ns)
Run abstract interpretation on a whole program.
virtual ctrace_set_ptrt abstract_traces_after(locationt l) const
Returns all of the histories that have reached the end of the instruction.
virtual bool visit(const irep_idt &function_id, trace_ptrt p, working_sett &working_set, const goto_programt &goto_program, const goto_functionst &goto_functions, const namespacet &ns)
Perform one step of abstract interpretation from trace t Depending on the instruction type it may com...
std::unique_ptr< ai_storage_baset > storage
virtual statet & get_state(trace_ptrt p)
Get the state for the given history, creating it with the factory if it doesn't exist.
ai_history_baset::trace_sett trace_sett
jsont output_json(const namespacet &ns, const goto_programt &goto_program) const
Output the abstract states for a single function as JSON.
void operator()(const irep_idt &function_id, const goto_programt &goto_program, const namespacet &ns)
Run abstract interpretation on a single function.
virtual ctrace_set_ptrt abstract_traces_before(locationt l) const
Returns all of the histories that have reached the start of the instruction.
virtual cstate_ptrt abstract_state_after(locationt l) const
Get a copy of the abstract state after the given instruction, without needing to know what kind of do...
bool visit_edge(const irep_idt &function_id, trace_ptrt p, const irep_idt &to_function_id, locationt to_l, trace_ptrt caller_history, const namespacet &ns, working_sett &working_set)
virtual void output(const namespacet &ns, const irep_idt &function_id, const goto_programt &goto_program, std::ostream &out) const
Output the abstract states for a single function.
xmlt output_xml(const namespacet &ns, const goto_programt &goto_program) const
Output the abstract states for a single function as XML.
jsont output_json(const goto_modelt &goto_model) const
Output the abstract states for a whole program as JSON.
message_handlert & message_handler
virtual bool visit_end_function(const irep_idt &function_id, trace_ptrt p, working_sett &working_set, const goto_programt &goto_program, const goto_functionst &goto_functions, const namespacet &ns)
virtual cstate_ptrt abstract_state_before(const trace_ptrt &p) const
The same interfaces but with histories.
virtual bool visit_function_call(const irep_idt &function_id, trace_ptrt p_call, working_sett &working_set, const goto_programt &goto_program, const goto_functionst &goto_functions, const namespacet &ns)
trace_ptrt entry_state(const goto_programt &goto_program)
Set the abstract state of the entry location of a single function to the entry state required by the ...
void operator()(const abstract_goto_modelt &goto_model)
Run abstract interpretation on a whole program.
virtual bool visit_edge_function_call(const irep_idt &calling_function_id, trace_ptrt p_call, locationt l_return, const irep_idt &callee_function_id, working_sett &working_set, const goto_programt &callee, const goto_functionst &goto_functions, const namespacet &ns)
void output(const goto_modelt &goto_model, std::ostream &out) const
Output the abstract states for a whole program.
virtual void clear()
Reset the abstract state.
std::unique_ptr< ai_domain_factory_baset > domain_factory
For creating domain objects.
ai_storage_baset::ctrace_set_ptrt ctrace_set_ptrt
virtual void initialize(const irep_idt &function_id, const goto_programt &goto_program)
Initialize all the abstract states for a single function.
xmlt output_xml(const goto_modelt &goto_model) const
Output the abstract states for the whole program as XML.
jsont output_json(const namespacet &ns, const goto_functionst::goto_functiont &goto_function) const
Output the abstract states for a single function as JSON.
virtual bool fixedpoint(trace_ptrt starting_trace, const irep_idt &function_id, const goto_programt &goto_program, const goto_functionst &goto_functions, const namespacet &ns)
Run the fixedpoint algorithm until it reaches a fixed point.
virtual std::unique_ptr< statet > make_temporary_state(const statet &s)
Make a copy of a state.
ai_history_baset::trace_ptrt trace_ptrt
void put_in_working_set(working_sett &working_set, trace_ptrt t)
trace_ptrt get_next(working_sett &working_set)
Get the next location from the work queue.
trace_sett working_sett
The work queue, sorted using the history's ordering operator.
virtual bool merge(const statet &src, trace_ptrt from, trace_ptrt to)
Merge the state src, flowing from tracet from to tracet to, into the state currently stored for trace...
virtual cstate_ptrt abstract_state_before(locationt l) const
Get a copy of the abstract state before the given instruction, without needing to know what kind of d...
virtual xmlt output_xml(const namespacet &ns, const irep_idt &function_id, const goto_programt &goto_program) const
Output the abstract states for a single function as XML.
void operator()(const irep_idt &function_id, const goto_functionst::goto_functiont &goto_function, const namespacet &ns)
Run abstract interpretation on a single function.
void output(const namespacet &ns, const goto_functionst::goto_functiont &goto_function, std::ostream &out) const
Output the abstract states for a function.
virtual jsont output_json(const namespacet &ns, const irep_idt &function_id, const goto_programt &goto_program) const
Output the abstract states for a single function as JSON.
std::unique_ptr< ai_history_factory_baset > history_factory
For creating history objects.
virtual void finalize()
Override this to add a cleanup or post-processing step after fixedpoint has run.
ai_storage_baset::cstate_ptrt cstate_ptrt
The interface offered by a domain, allows code to manipulate domains without knowing their exact type...
goto_programt::const_targett locationt
std::shared_ptr< const ai_history_baset > trace_ptrt
History objects are intended to be immutable so they can be shared to reduce memory overhead.
static const trace_ptrt no_caller_history
std::set< trace_ptrt, compare_historyt > trace_sett
An easy factory implementation for histories that don't need parameters.
ai_recursive_interproceduralt(std::unique_ptr< ai_history_factory_baset > &&hf, std::unique_ptr< ai_domain_factory_baset > &&df, std::unique_ptr< ai_storage_baset > &&st, message_handlert &mh)
bool visit_edge_function_call(const irep_idt &calling_function_id, trace_ptrt p_call, locationt l_return, const irep_idt &callee_function_id, working_sett &working_set, const goto_programt &callee, const goto_functionst &goto_functions, const namespacet &ns) override
std::shared_ptr< const trace_sett > ctrace_set_ptrt
std::shared_ptr< const statet > cstate_ptrt
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
ait(std::unique_ptr< ai_domain_factory_baset > &&df)
goto_programt::const_targett locationt
null_message_handlert no_logging
void dummy(const domainT &s)
This function exists to enforce that domainT is derived from ai_domain_baset.
virtual statet & get_state(locationt l)
Base class for concurrency-aware abstract interpretation.
ai_baset::working_sett working_sett
concurrency_aware_ait(std::unique_ptr< ai_domain_factory_baset > &&df)
virtual bool merge_shared(const statet &src, locationt from, locationt to, const namespacet &ns)
void fixedpoint(ai_baset::trace_ptrt start_trace, const goto_functionst &goto_functions, const namespacet &ns) override
typename statet::locationt locationt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
A collection of goto functions.
function_mapt function_map
::goto_functiont goto_functiont
symbol_tablet symbol_table
Symbol table.
goto_functionst goto_functions
GOTO functions.
A generic container class for the GOTO intermediate representation of one function.
instructionst::const_iterator const_targett
The most conventional storage; one domain per location.
statet & get_state(trace_ptrt p, const ai_domain_factory_baset &fac) override
Look up the analysis state for a given history, instantiating a new domain if required.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
#define SINCE(year, month, day, msg)
#define forall_goto_program_instructions(it, program)
Over-approximate Concurrency for Threaded Goto Programs.
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.