41 const goto_functionst::function_mapt::const_iterator,
68 const std::unordered_set<symbol_exprt, irep_hash> &)
const;
72 std::vector<symbol_exprt> &nondet_symbols)
const;
85 std::vector<symbol_exprt> &nondet_symbols)
const;
110 const std::string &suffix)
const
124 auto incoming_it =
incoming.find(loc);
128 std::vector<symbol_exprt> symbols;
129 symbols.reserve(incoming_it->second.size());
131 for(
auto &loc_in : incoming_it->second)
137 loc_in->is_goto() && !loc_in->condition().is_true() &&
138 loc != std::next(loc_in))
165 const exprt &what)
const
173 std::vector<symbol_exprt> &nondet_symbols)
const
175 if(what.
id() == ID_side_effect)
178 auto statement = side_effect.get_statement();
179 if(statement == ID_nondet)
184 auto symbol =
symbol_exprt(identifier, side_effect.type());
185 nondet_symbols.push_back(symbol);
186 return std::move(symbol);
188 else if(statement == ID_va_start)
211 const std::unordered_set<symbol_exprt, irep_hash> &bound_symbols)
const
215 if(what.
id() == ID_symbol)
225 else if(bound_symbols.find(symbol_expr) == bound_symbols.end())
233 what.
id() == ID_dereference || what.
id() == ID_member ||
234 what.
id() == ID_index)
238 else if(what.
id() == ID_forall || what.
id() == ID_exists)
241 auto new_bound_symbols = bound_symbols;
243 for(
const auto &v : new_quantifier_expr.variables())
244 new_bound_symbols.insert(v);
247 loc, state, new_quantifier_expr.where(), new_bound_symbols);
249 return std::move(new_quantifier_expr);
251 else if(what.
id() == ID_address_of)
256 else if(what.
id() == ID_live_object)
263 else if(what.
id() == ID_writeable_object)
267 loc, state, writeable_object_expr.pointer(), bound_symbols);
270 else if(what.
id() == ID_is_dynamic_object)
274 loc, state, is_dynamic_object_expr.address(), bound_symbols);
277 else if(what.
id() == ID_object_size)
284 else if(what.
id() == ID_r_ok || what.
id() == ID_w_ok || what.
id() == ID_rw_ok)
292 auto new_id = what.
id() == ID_r_ok ? ID_state_r_ok
293 : what.
id() == ID_w_ok ? ID_state_w_ok
297 else if(what.
id() == ID_is_cstring)
305 else if(what.
id() == ID_cstrlen)
313 else if(what.
id() == ID_is_sentinel_dll)
320 loc, state, is_sentinel_dll_expr.
op0(), bound_symbols);
322 loc, state, is_sentinel_dll_expr.
op1(), bound_symbols);
325 else if(what.
operands().size() == 3)
329 loc, state, is_sentinel_dll_expr.
op0(), bound_symbols);
331 loc, state, is_sentinel_dll_expr.
op1(), bound_symbols);
333 loc, state, is_sentinel_dll_expr.
op2(), bound_symbols);
337 DATA_INVARIANT(
false,
"is_sentinel_dll expressions have 2 or 3 operands");
339 else if(what.
id() == ID_side_effect)
345 (what.
id() == ID_equal || what.
id() == ID_notequal) &&
353 const auto &struct_type = ns.
follow_tag(type);
357 for(
auto &field : struct_type.components())
361 auto equality =
equal_exprt(lhs_member, rhs_member);
362 auto equality_evaluated =
364 conjuncts.push_back(std::move(equality_evaluated));
367 if(what.
id() == ID_equal)
408 std::move(condition)),
415 if(expr.
id() == ID_symbol)
419 else if(expr.
id() == ID_member)
422 auto compound_address =
address_rec(loc, state, std::move(compound));
425 CHECK_RETURN(compound_address.type().id() == ID_pointer);
427 if(expr.
type().
id() == ID_array)
431 std::move(compound_address),
441 else if(expr.
id() == ID_index)
444 auto index_evaluated =
446 auto array_address =
address_rec(loc, state, std::move(array));
450 std::move(array_address),
451 std::move(index_evaluated),
454 else if(expr.
id() == ID_dereference)
456 else if(expr.
id() == ID_string_constant)
462 else if(expr.
id() == ID_array)
468 else if(expr.
id() == ID_struct)
474 else if(expr.
id() == ID_union)
480 else if(expr.
id() == ID_side_effect)
484 "address of side effect " +
488 else if(expr.
id() == ID_typecast)
507 std::vector<symbol_exprt> &nondet_symbols)
const
509 if(lhs.
type().
id() == ID_struct_tag)
514 exprt new_state = state;
515 for(
auto &field : struct_type.components())
520 if(rhs.
id() == ID_struct)
523 rhs.
id() == ID_side_effect &&
531 loc, new_state, lhs_member, rhs_member, nondet_symbols);
536 else if(lhs.
type().
id() == ID_array)
541 if(array_type.size().is_constant())
545 exprt new_state = state;
553 if(rhs.
id() == ID_array)
556 rhs.
id() == ID_side_effect &&
564 loc, new_state, lhs_index, rhs_index, nondet_symbols);
591 std::vector<symbol_exprt> nondet_symbols;
597 binding.insert(binding.end(), nondet_symbols.begin(), nondet_symbols.end());
614 incoming[it->get_target()].push_back(it);
619 auto next = std::next(it);
620 if(it->is_goto() && it->condition().is_true())
632 if(src.
id() == ID_not)
653 auto identifier =
function.get_identifier();
659 if(identifier ==
"malloc")
663 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[0]);
665 auto lhs_address =
address_rec(loc, state, loc->call_lhs());
668 state, lhs_address,
allocate_exprt(state, size_evaluated, lhs_type));
675 if(identifier ==
"posix_memalign")
680 auto memptr_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[0]);
681 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[2]);
685 state, memptr_evaluated,
allocate_exprt(state, size_evaluated, lhs_type));
692 if(identifier ==
"realloc")
696 auto pointer_evaluated =
698 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[1]);
700 auto lhs_address =
address_rec(loc, state, loc->call_lhs());
712 if(identifier ==
"free")
716 auto address_evaluated =
731 if(!f->second.body_available())
734 if(loc->call_lhs().is_not_nil())
737 loc->call_lhs().type(), loc->source_location());
748 std::cout <<
"**** WARNING: no body for function " << identifier <<
'\n';
764 const auto &arguments = loc->call_arguments();
767 for(std::size_t i = 0; i < type.parameters().size(); i++)
770 f->second.parameter_identifiers[i], type.parameters()[i].type()));
776 if(arguments.size() > type.parameters().size())
778 std::vector<exprt> va_args_elements;
781 for(std::size_t i = type.parameters().size(); i < arguments.size(); i++)
783 auto index = i - type.parameters().size();
790 va_args_elements.push_back(
796 auto va_count = va_args_elements.size();
799 auto array_identifier =
801 auto array_symbol =
symbol_exprt(array_identifier, array_type);
803 for(std::size_t i = 0; i < va_count; i++)
809 auto value = va_args_elements[i];
829 auto new_state_prefix =
833 body_state_encoding.
encode(
839 function_entry_state,
844 auto exit_loc = std::prev(f->second.body.instructions.end());
854 if(loc->call_lhs().is_not_nil())
856 auto rhs =
symbol_exprt(
"return_value", loc->call_lhs().type());
858 auto address =
address_rec(exit_loc, state, loc->call_lhs());
880 const auto &
function = loc->call_function();
881 if(
function.
id() == ID_dereference)
885 "can't do function pointers", loc->source_location());
887 else if(
function.
id() == ID_symbol)
894 false,
"got function that's neither a symbol nor a function pointer");
899 goto_functionst::function_mapt::const_iterator f_entry,
902 const auto &goto_function = f_entry->second;
904 if(goto_function.body.instructions.empty())
932 const std::string &state_prefix,
933 const std::vector<irep_idt> &call_stack,
934 const std::string &annotation,
936 const exprt &return_lhs,
975 auto &lhs = loc->assign_lhs();
976 auto &rhs = loc->assign_rhs();
978 DATA_INVARIANT(lhs.type() == rhs.type(),
"assignment type consistency");
981 lhs.id() == ID_symbol &&
990 lhs.id() == ID_symbol &&
1000 else if(loc->is_assume())
1004 auto condition_evaluated =
evaluate_expr(loc, state, loc->condition());
1008 condition_evaluated,
1011 else if(loc->is_goto())
1014 const auto &condition = loc->condition();
1016 if(condition.is_true())
1023 auto condition_evaluated =
evaluate_expr(loc, state, condition);
1027 condition_evaluated,
1036 else if(loc->is_assert())
1045 loc->is_skip() || loc->is_assert() || loc->is_location() ||
1046 loc->is_end_function())
1051 else if(loc->is_atomic_begin() || loc->is_atomic_end())
1056 else if(loc->is_other())
1058 auto &code = loc->code();
1059 auto &statement = code.get_statement();
1060 if(statement == ID_array_set)
1063 code.operands().size() == 2,
"array_set has two operands");
1073 else if(loc->is_decl())
1077 s_in,
address_rec(loc, s_in, loc->decl_symbol()));
1081 else if(loc->is_dead())
1086 s_in,
address_rec(loc, s_in, loc->dead_symbol()));
1090 else if(loc->is_function_call())
1094 else if(loc->is_set_return_value())
1096 const auto &rhs = loc->return_value();
1110 std::cout <<
"X: " << loc->type() <<
'\n';
1118 bool program_is_inlined,
1119 std::optional<irep_idt> contract,
1122 if(program_is_inlined)
1134 else if(contract.has_value())
1139 if(ns.
lookup(*contract, symbol))
1141 "The given function was not found",
"contract");
1145 "The given function has no contract",
"contract");
1160 for(
auto &f : sorted)
1181 bool program_is_inlined,
1182 std::optional<irep_idt> contract,
1185 switch(state_encoding_format)
1218 switch(state_encoding_format)
1238 bool program_is_inlined,
1239 std::optional<irep_idt> contract,
1245 state_encoding(goto_model, program_is_inlined, contract, container);
pointer_typet pointer_type(const typet &subtype)
Operator to return the address of an object.
const typet & element_type() const
The type of the elements of the array.
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly two argu...
std::vector< symbol_exprt > variablest
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Operator to return the address of an array element relative to a base address.
virtual void annotation(const std::string &)
void set_source_location(source_locationt __source_location)
Base class for all expressions.
std::vector< exprt > operandst
const source_locationt & source_location() const
typet & type()
Return the type of the expression.
Operator to return the address of a field relative to a base address.
Application of (mathematical) function.
function_mapt function_map
std::vector< function_mapt::const_iterator > sorted() const
returns a vector of the iterators in alphabetical order
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
symbol_tablet symbol_table
Symbol table.
goto_functionst goto_functions
GOTO functions.
instructionst instructions
The list of instructions in the goto program.
instructionst::const_iterator const_targett
Thrown when a goto program that's being processed is in an invalid format, for example passing the wr...
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
const std::string & id_string() const
const irep_idt & id() const
A (mathematical) lambda expression.
Extract member of struct or union.
const exprt & struct_op() const
irep_idt get_component_name() const
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
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().
Operator to return the address of an object.
const typet & base_type() const
The type of the data what we point to.
A side_effect_exprt that returns a non-deterministically chosen value.
state_encodingt(const goto_modelt &__goto_model)
exprt evaluate_expr_rec(loct, const exprt &, const exprt &, const std::unordered_set< symbol_exprt, irep_hash > &) const
void setup_incoming(const goto_functiont &)
symbol_exprt in_state_expr(loct) const
void function_call(goto_programt::const_targett, encoding_targett &)
const goto_modelt & goto_model
exprt address_rec(loct, const exprt &, exprt) const
goto_programt::const_targett loct
void encode(const goto_functiont &, const irep_idt function_identifier, const std::string &state_prefix, const std::vector< irep_idt > &call_stack, const std::string &annotation, const symbol_exprt &entry_state, const exprt &return_lhs, encoding_targett &)
symbol_exprt out_state_expr(loct) const
static symbol_exprt va_args(irep_idt function)
exprt assignment_constraint_rec(loct, exprt state, exprt lhs, exprt rhs, std::vector< symbol_exprt > &nondet_symbols) const
std::map< loct, std::vector< loct >, goto_programt::target_less_than > incomingt
exprt replace_nondet_rec(loct, const exprt &, std::vector< symbol_exprt > &nondet_symbols) const
void function_call_symbol(goto_programt::const_targett, encoding_targett &)
exprt evaluate_expr(loct, const exprt &, const exprt &) const
irep_idt function_identifier
symbol_exprt state_expr_with_suffix(loct, const std::string &suffix) const
std::vector< irep_idt > call_stack
exprt assignment_constraint(loct, exprt lhs, exprt rhs) const
std::vector< symbol_exprt > incoming_symbols(loct) const
void operator()(const goto_functionst::function_mapt::const_iterator, encoding_targett &)
static exprt state_lambda_expr(exprt)
exprt forall_states_expr(loct, exprt) const
Expression to hold a symbol (variable)
irep_idt name
The unique identifier.
An expression with three operands.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
bool has_prefix(const std::string &s, const std::string &prefix)
void equality_propagation(std::vector< exprt > &constraints)
#define forall_goto_program_instructions(it, program)
std::optional< code_with_contract_typet > get_contract(const irep_idt &function_identifier, const namespacet &ns)
Instrument Given Invariants.
const std::string & id2string(const irep_idt &d)
API to expression classes for 'mathematical' expressions.
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
API to expression classes for Pointers.
const object_size_exprt & to_object_size_expr(const exprt &expr)
Cast an exprt to a object_size_exprt.
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
const live_object_exprt & to_live_object_expr(const exprt &expr)
Cast an exprt to a live_object_exprt.
const cstrlen_exprt & to_cstrlen_expr(const exprt &expr)
Cast an exprt to a cstrlen_exprt.
const writeable_object_exprt & to_writeable_object_expr(const exprt &expr)
Cast an exprt to a writeable_object_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const is_dynamic_object_exprt & to_is_dynamic_object_expr(const exprt &expr)
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
exprt simplify_expr(exprt src, const namespacet &ns)
void solver(std::vector< framet > &frames, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const solver_optionst &solver_options, const namespacet &ns, std::vector< propertyt > &properties, std::size_t property_index)
#define CHECK_RETURN(CONDITION)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
static symbol_exprt state_expr()
static mathematical_function_typet state_predicate_type()
solver_resultt state_encoding_solver(const goto_modelt &goto_model, bool program_is_inlined, std::optional< irep_idt > contract, const solver_optionst &solver_options)
void state_encoding(const goto_modelt &goto_model, bool program_is_inlined, std::optional< irep_idt > contract, encoding_targett &dest)
void variable_encoding(const goto_modelt &goto_model, state_encoding_formatt state_encoding_format, std::ostream &out)
std::set< irep_idt > no_body_warnings
static exprt simplifying_not(exprt src)
side_effect_exprt & to_side_effect_expr(exprt &expr)
exprt conjunction(const exprt::operandst &op)
1) generates a conjunction for two or more operands 2) for one operand, returns the operand 3) return...
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const ternary_exprt & to_ternary_expr(const exprt &expr)
Cast an exprt to a ternary_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
A total order over targett and const_targett.