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
113 state_prefix + std::to_string(loc->location_number) + suffix;
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() !=
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)
182 std::to_string(loc->location_number) +
"-" +
183 std::to_string(nondet_symbols.size());
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)
343 side_effect.get_statement() == ID_allocate &&
344 side_effect.operands().size() == 2 &&
345 side_effect.type().id() == ID_pointer)
364 loc, state, side_effect.
operands().front(), bound_symbols);
372 (what.
id() == ID_equal || what.
id() == ID_notequal) &&
380 const auto &struct_type = ns.
follow_tag(type);
384 for(
auto &field : struct_type.components())
388 auto equality =
equal_exprt(lhs_member, rhs_member);
389 auto equality_evaluated =
391 conjuncts.push_back(std::move(equality_evaluated));
394 if(what.
id() == ID_equal)
435 std::move(condition)),
442 if(expr.
id() == ID_symbol)
446 else if(expr.
id() == ID_member)
449 auto compound_address =
address_rec(loc, state, std::move(compound));
452 CHECK_RETURN(compound_address.type().id() == ID_pointer);
454 if(expr.
type().
id() == ID_array)
458 std::move(compound_address),
468 else if(expr.
id() == ID_index)
471 auto index_evaluated =
473 auto array_address =
address_rec(loc, state, std::move(array));
477 std::move(array_address),
478 std::move(index_evaluated),
481 else if(expr.
id() == ID_dereference)
483 else if(expr.
id() == ID_string_constant)
489 else if(expr.
id() == ID_array)
495 else if(expr.
id() == ID_struct)
501 else if(expr.
id() == ID_union)
507 else if(expr.
id() == ID_side_effect)
511 "address of side effect " +
515 else if(expr.
id() == ID_typecast)
534 std::vector<symbol_exprt> &nondet_symbols)
const
536 if(lhs.
type().
id() == ID_struct_tag)
541 exprt new_state = state;
542 for(
auto &field : struct_type.components())
547 if(rhs.
id() == ID_struct)
550 rhs.
id() == ID_side_effect &&
558 loc, new_state, lhs_member, rhs_member, nondet_symbols);
563 else if(lhs.
type().
id() == ID_array)
568 if(array_type.size().is_constant())
572 exprt new_state = state;
580 if(rhs.
id() == ID_array)
583 rhs.
id() == ID_side_effect &&
591 loc, new_state, lhs_index, rhs_index, nondet_symbols);
618 std::vector<symbol_exprt> nondet_symbols;
624 binding.insert(binding.end(), nondet_symbols.begin(), nondet_symbols.end());
641 incoming[it->get_target()].push_back(it);
646 auto next = std::next(it);
647 if(it->is_goto() && it->condition() ==
true)
659 if(src.
id() == ID_not)
680 auto identifier = function.identifier();
686 if(identifier ==
"malloc")
690 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[0]);
692 auto lhs_address =
address_rec(loc, state, loc->call_lhs());
695 state, lhs_address,
allocate_exprt(state, size_evaluated, lhs_type));
702 if(identifier ==
"posix_memalign")
707 auto memptr_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[0]);
708 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[2]);
712 state, memptr_evaluated,
allocate_exprt(state, size_evaluated, lhs_type));
719 if(identifier ==
"realloc")
723 auto pointer_evaluated =
725 auto size_evaluated =
evaluate_expr(loc, state, loc->call_arguments()[1]);
727 auto lhs_address =
address_rec(loc, state, loc->call_lhs());
739 if(identifier ==
"free")
743 auto address_evaluated =
753 auto f =
goto_model.goto_functions.function_map.find(identifier);
754 if(f ==
goto_model.goto_functions.function_map.end())
758 if(!f->second.body_available())
761 if(loc->call_lhs().is_not_nil())
764 loc->call_lhs().type(), loc->source_location());
775 std::cout <<
"**** WARNING: no body for function " << identifier <<
'\n';
791 const auto &arguments = loc->call_arguments();
794 for(std::size_t i = 0; i < type.parameters().size(); i++)
797 f->second.parameter_identifiers[i], type.parameters()[i].type()));
803 if(arguments.size() > type.parameters().size())
805 std::vector<exprt> va_args_elements;
808 for(std::size_t i = type.parameters().size(); i < arguments.size(); i++)
810 auto index = i - type.parameters().size();
812 std::to_string(loc->location_number) +
813 "::" + std::to_string(index);
817 va_args_elements.push_back(
823 auto va_count = va_args_elements.size();
826 auto array_identifier =
827 "va_arg_array::" +
state_prefix + std::to_string(loc->location_number);
828 auto array_symbol =
symbol_exprt(array_identifier, array_type);
830 for(std::size_t i = 0; i < va_count; i++)
836 auto value = va_args_elements[i];
856 auto new_state_prefix =
857 state_prefix + std::to_string(loc->location_number) +
".";
860 body_state_encoding.encode(
866 function_entry_state,
871 auto exit_loc = std::prev(f->second.body.instructions.end());
873 new_state_prefix + std::to_string(exit_loc->location_number);
881 if(loc->call_lhs().is_not_nil())
883 auto rhs =
symbol_exprt(
"return_value", loc->call_lhs().type());
885 auto address =
address_rec(exit_loc, state, loc->call_lhs());
907 const auto &function = loc->call_function();
908 if(function.id() == ID_dereference)
912 "can't do function pointers", loc->source_location());
914 else if(function.id() == ID_symbol)
921 false,
"got function that's neither a symbol nor a function pointer");
926 goto_functionst::function_mapt::const_iterator f_entry,
929 const auto &goto_function = f_entry->second;
931 if(goto_function.body.instructions.empty())
1000 if(loc->is_assign())
1002 auto &lhs = loc->assign_lhs();
1003 auto &rhs = loc->assign_rhs();
1005 DATA_INVARIANT(lhs.type() == rhs.type(),
"assignment type consistency");
1008 lhs.id() == ID_symbol &&
1017 lhs.id() == ID_symbol &&
1027 else if(loc->is_assume())
1031 auto condition_evaluated =
evaluate_expr(loc, state, loc->condition());
1035 condition_evaluated,
1038 else if(loc->is_goto())
1041 const auto &condition = loc->condition();
1043 if(condition ==
true)
1050 auto condition_evaluated =
evaluate_expr(loc, state, condition);
1054 condition_evaluated,
1063 else if(loc->is_assert())
1072 loc->is_skip() || loc->is_assert() || loc->is_location() ||
1073 loc->is_end_function())
1078 else if(loc->is_atomic_begin() || loc->is_atomic_end())
1083 else if(loc->is_other())
1085 auto &code = loc->code();
1086 auto &statement = code.get_statement();
1087 if(statement == ID_array_set)
1090 code.operands().size() == 2,
"array_set has two operands");
1100 else if(loc->is_decl())
1104 s_in,
address_rec(loc, s_in, loc->decl_symbol()));
1108 else if(loc->is_dead())
1113 s_in,
address_rec(loc, s_in, loc->dead_symbol()));
1117 else if(loc->is_function_call())
1121 else if(loc->is_set_return_value())
1123 const auto &rhs = loc->return_value();
1137 std::cout <<
"X: " << loc->type() <<
'\n';
1145 bool program_is_inlined,
1146 std::optional<irep_idt> contract,
1149 if(program_is_inlined)
1161 else if(contract.has_value())
1166 if(ns.
lookup(*contract, symbol))
1168 "The given function was not found",
"contract");
1172 "The given function has no contract",
"contract");
1187 for(
auto &f : sorted)
1208 bool program_is_inlined,
1209 std::optional<irep_idt> contract,
1212 switch(state_encoding_format)
1245 switch(state_encoding_format)
1265 bool program_is_inlined,
1266 std::optional<irep_idt> contract,
1272 state_encoding(goto_model, program_is_inlined, contract, container);
unsignedbv_typet size_type()
pointer_typet pointer_type(const typet &subtype)
Operator to return the address of an object.
Boolean AND All operands must be boolean, and the result is always boolean.
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
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
typet & type()
Return the type of the expression.
const source_locationt & source_location() const
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
instructiont::target_less_than target_less_than
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
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::map< loct, std::vector< loct >, goto_programt::target_less_than > incomingt
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)
static symbol_exprt state_expr()
static exprt simplifying_not(exprt src)
static mathematical_function_typet state_predicate_type()
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 live_object_exprt & to_live_object_expr(const exprt &expr)
Cast an exprt to a live_object_exprt.
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
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 address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
const object_size_exprt & to_object_size_expr(const exprt &expr)
Cast an exprt to a object_size_exprt.
const is_dynamic_object_exprt & to_is_dynamic_object_expr(const exprt &expr)
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)
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(exprt a, exprt b)
Conjunction of two expressions.
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 ternary_exprt & to_ternary_expr(const exprt &expr)
Cast an exprt to a ternary_exprt.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.