33 if(lhs.
id()==ID_address_of)
35 else if(lhs.
id()==ID_typecast)
37 else if(lhs.
id()==ID_symbol)
48 const std::set<irep_idt> &cleanup_functions)
50 if(lhs.
id()==ID_symbol)
57 if(cleanup_functions.empty())
60 cleanup_map[identifier].cleanup_functions=cleanup_functions;
67 const std::set<irep_idt> &alias_set)
69 if(lhs.
id()==ID_symbol)
78 for(
const auto &alias : alias_set)
88 std::set<irep_idt> &cleanup_functions)
90 if(rhs.
id()==ID_symbol)
97 const escape_domaint::cleanup_mapt::const_iterator m_it=
101 cleanup_functions.insert(m_it->second.cleanup_functions.begin(),
102 m_it->second.cleanup_functions.end());
105 else if(rhs.
id()==ID_if)
110 else if(rhs.
id()==ID_typecast)
118 std::set<irep_idt> &alias_set)
120 if(rhs.
id()==ID_symbol)
126 alias_set.insert(identifier);
128 for(
const auto &alias :
aliases)
130 alias_set.insert(alias);
133 else if(rhs.
id()==ID_if)
138 else if(rhs.
id()==ID_typecast)
142 else if(rhs.
id()==ID_address_of)
150 std::set<irep_idt> &alias_set)
152 if(rhs.
id()==ID_symbol)
155 alias_set.insert(
"&"+
id2string(identifier));
157 else if(rhs.
id()==ID_if)
162 else if(rhs.
id()==ID_dereference)
175 locationt from{trace_from->current_location()};
186 switch(instruction.
type())
193 std::set<irep_idt> cleanup_functions;
197 std::set<irep_idt> rhs_aliases;
217 if(
function.
id()==ID_symbol)
229 if(!cleanup_function.
empty())
232 std::set<irep_idt> lhs_set;
235 for(
const auto &l : lhs_set)
237 cleanup_map[l].cleanup_functions.insert(cleanup_function);
254 DATA_INVARIANT(
false,
"Exceptions must be removed before analysis");
257 DATA_INVARIANT(
false,
"SET_RETURN_VALUE must be removed before analysis");
270 DATA_INVARIANT(
false,
"Unclear what is a safe over-approximation of OTHER");
275 DATA_INVARIANT(
false,
"Only complete instructions can be analyzed");
293 out << cleanup.first <<
':';
294 for(
const auto &
id : cleanup.second.cleanup_functions)
314 out <<
"Aliases: " << *a_it1;
317 out <<
' ' << *a_it2;
333 const std::set<irep_idt> &b_cleanup=cleanup.second.cleanup_functions;
334 std::set<irep_idt> &a_cleanup=
cleanup_map[cleanup.first].cleanup_functions;
335 auto old_size=a_cleanup.size();
336 a_cleanup.insert(b_cleanup.begin(), b_cleanup.end());
337 if(a_cleanup.size()!=old_size)
343 for(cleanup_mapt::iterator a_it=
cleanup_map.begin();
347 if(a_it->second.cleanup_functions.empty())
381 std::set<irep_idt> &cleanup_functions)
const
383 if(lhs.
id()==ID_symbol)
388 const escape_domaint::cleanup_mapt::const_iterator m_it=
397 for(
const auto &alias :
aliases)
406 cleanup_functions.insert(
407 m_it->second.cleanup_functions.begin(),
408 m_it->second.cleanup_functions.end());
418 const std::set<irep_idt> &cleanup_functions,
424 for(
const auto &cleanup : cleanup_functions)
429 goto_function.body.insert_before_swap(location);
466 std::set<irep_idt> cleanup_functions;
469 gf_entry.second, i_it, assign_lhs, cleanup_functions,
false, ns);
473 const auto &dead_symbol = instruction.
dead_symbol();
475 std::set<irep_idt> cleanup_functions1;
479 const escape_domaint::cleanup_mapt::const_iterator m_it =
485 cleanup_functions1.insert(
486 m_it->second.cleanup_functions.begin(),
487 m_it->second.cleanup_functions.end());
490 std::set<irep_idt> cleanup_functions2;
492 d.
check_lhs(dead_symbol, cleanup_functions2);
495 gf_entry.second, i_it, dead_symbol, cleanup_functions1,
true, ns);
497 gf_entry.second, i_it, dead_symbol, cleanup_functions2,
false, ns);
499 for(
const auto &c : cleanup_functions1)
505 for(
const auto &c : cleanup_functions2)
Operator to return the address of an object.
This is the basic interface of the abstract interpreter with default implementations of the core func...
ai_history_baset::trace_ptrt trace_ptrt
goto_programt::const_targett locationt
const escape_domaint & operator[](locationt l) const
Find the analysis result for a given location.
virtual statet & get_state(trace_ptrt p)
Get the state for the given history, creating it with the factory if it doesn't exist.
goto_instruction_codet representation of a function call statement.
const parameterst & parameters() const
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
void instrument(goto_modelt &)
void insert_cleanup(goto_functionst::goto_functiont &, goto_programt::targett, const exprt &, const std::set< irep_idt > &, bool is_object, const namespacet &)
bool merge(const escape_domaint &b, trace_ptrt from, trace_ptrt to)
void assign_lhs_cleanup(const exprt &, const std::set< irep_idt > &)
void check_lhs(const exprt &, std::set< irep_idt > &) const
void get_rhs_aliases(const exprt &, std::set< irep_idt > &)
irep_idt get_function(const exprt &)
void get_rhs_aliases_address_of(const exprt &, std::set< irep_idt > &)
void transform(const irep_idt &function_from, trace_ptrt trace_from, const irep_idt &function_to, trace_ptrt trace_to, ai_baset &ai, const namespacet &ns) final override
how function calls are treated: a) there is an edge from each call site to the function head b) there...
bool is_tracked(const symbol_exprt &)
void assign_lhs_aliases(const exprt &, const std::set< irep_idt > &)
void output(std::ostream &out, const ai_baset &ai, const namespacet &ns) const final override
void get_rhs_cleanup(const exprt &, std::set< irep_idt > &)
Base class for all expressions.
source_locationt & add_source_location()
function_mapt function_map
::goto_functiont goto_functiont
symbol_tablet symbol_table
Symbol table.
goto_functionst goto_functions
GOTO functions.
This class represents an instruction in the GOTO intermediate representation.
const exprt & call_function() const
Get the function that is called for FUNCTION_CALL.
const exprt & assign_rhs() const
Get the rhs of the assignment for ASSIGN.
const symbol_exprt & dead_symbol() const
Get the symbol for DEAD.
const symbol_exprt & decl_symbol() const
Get the declared symbol for DECL.
const exprt & assign_lhs() const
Get the lhs of the assignment for ASSIGN.
goto_program_instruction_typet type() const
What kind of instruction?
const exprt::operandst & call_arguments() const
Get the arguments of a FUNCTION_CALL.
instructionst::iterator targett
static instructiont make_function_call(const code_function_callt &_code, const source_locationt &l=source_locationt::nil())
Create a function call instruction.
const irep_idt & id() const
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Expression to hold a symbol (variable)
const irep_idt & get_identifier() const
const char * to_string() const
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
void isolate(const_iterator it)
const T & find(const_iterator it) const
bool make_union(const T &a, const T &b)
bool same_set(const T &a, const T &b) const
typename numbering_typet::const_iterator const_iterator
bool is_root(const T &a) const
Field-insensitive, location-sensitive, over-approximative escape analysis.
#define Forall_goto_program_instructions(it, program)
const std::string & id2string(const irep_idt &d)
API to expression classes for Pointers.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.