Go to the documentation of this file.
31 exprt &dest,
bool write)
34 if(
build(
object, dest, write))
48 !(dest.
type().
id() == ID_array && a_t.
id() == ID_pointer &&
53 log.warning() <<
"warning: inconsistent abstract type for "
63 return type.
id() == ID_pointer &&
69 return type.
id()==ID_pointer;
82 : sym_suffix(
"#str$fcn"),
83 goto_model(goto_model),
84 ns(goto_model.symbol_table),
86 message_handler(_message_handler)
92 s.components()[1].set_pretty_name(
"length");
93 s.components()[2].set_pretty_name(
"size");
141 if(type.
id() != ID_code)
146 goto_functionst::function_mapt::iterator fct_entry =
152 fct_entry->second.parameter_identifiers);
165 abstract(gf_entry.second.body);
169 goto_functionst::function_mapt::iterator
202 goto_functiont::parameter_identifierst::const_iterator param_id_it =
203 parameter_identifiers.begin();
204 for(
const auto ¶meter : fct_type.
parameters())
207 if(abstract_type.
is_nil())
210 str_args.push_back(
add_parameter(fct_symbol, abstract_type, *param_id_it));
214 for(
const auto &new_param : str_args)
215 parameter_identifiers.push_back(new_param.get_identifier());
217 fct_type.
parameters().end(), str_args.begin(), str_args.end());
233 :
ns.
lookup(identifier).base_name) +
243 str_parameter.set_base_name(param_symbol.
base_name);
244 str_parameter.set_identifier(param_symbol.
name);
246 if(!identifier.
empty())
249 return str_parameter;
257 it=
abstract(dest, it);
269 typedef std::unordered_map<irep_idt, goto_programt::targett> available_declst;
270 available_declst available_decls;
276 available_decls.insert(
277 std::make_pair(it->decl_symbol().get_identifier(), it));
280 for(
const auto &l :
locals)
285 available_declst::const_iterator entry=available_decls.find(l.first);
287 if(available_declst::const_iterator(available_decls.end())!=entry)
289 ref_instr=entry->second;
312 decl1->code_nonconst().add_source_location() = ref_instr->source_location();
328 assignment1->code_nonconst().add_source_location() =
329 ref_instr->source_location();
337 if(symbol.
type.
id() == ID_array || symbol.
type.
id() == ID_pointer)
350 if(symbol.
type.
id() == ID_array)
356 symbol.
type.
id() == ID_union_tag ||
369 struct_union_typet::componentst::const_iterator it2=components.begin();
370 for(struct_union_typet::componentst::const_iterator
371 it=s_components.begin();
372 it!=s_components.end() && it2!=components.end();
375 if(it->get_name()!=it2->get_name())
379 it2->type().id() == ID_pointer || it2->type().id() == ID_array ||
380 it2->type().id() == ID_struct_tag || it2->type().id() == ID_union_tag)
383 dest, ref_instr, symbol, it2->get_name(), it2->
type(), it->type());
390 assignment1->code_nonconst().add_source_location() =
391 ref_instr->source_location();
399 components.size() == seen,
400 "some of the symbol's component names were not found in the source");
412 const typet &source_type)
414 std::string suffix=
"$strdummy";
415 if(!component_name.
empty())
416 suffix=
"#"+
id2string(component_name)+suffix;
421 new_symbol.
type=type;
423 new_symbol.
location = ref_instr->source_location();
424 new_symbol.
name=dummy_identifier;
436 decl->code_nonconst().add_source_location() = ref_instr->source_location();
440 source_type.
id() == ID_array &&
464 assignment1->code_nonconst().add_source_location() =
465 ref_instr->source_location();
488 it->condition_nonconst(),
false, it->source_location());
528 exprt &lhs = target->assign_lhs_nonconst();
529 exprt &rhs = target->assign_rhs_nonconst();
541 const typet &type = target->assign_lhs().type();
543 if(type.
id() == ID_pointer || type.
id() == ID_array)
554 auto arguments =
as_const(*target).call_arguments();
557 for(
const auto &arg : arguments)
560 if(abstract_type.
is_nil())
563 str_args.push_back(
exprt());
569 if(str_args.back().type().id()==ID_array &&
570 abstract_type.
id()==ID_pointer)
575 "argument array type differs from formal parameter pointer type");
585 if(!str_args.empty())
587 arguments.insert(arguments.end(), str_args.begin(), str_args.end());
591 for(
const auto &arg : str_args)
594 target->call_arguments() = std::move(arguments);
600 if(expr.
id()==
"is_zero_string" ||
601 expr.
id()==
"zero_string_length" ||
602 expr.
id()==
"buffer_size")
617 if(expr.
id()==
"is_zero_string")
624 else if(expr.
id()==
"zero_string_length")
631 else if(expr.
id()==
"buffer_size")
644 const exprt &pointer,
650 if(pointer.
id()==ID_typecast)
656 op.
type().
id() != ID_pointer ||
663 return build(op, what, write, source_location);
688 abstraction_types_mapt::const_iterator map_entry =
691 return map_entry->second;
701 return map_entry->second;
707 abstraction_types_mapt::const_iterator known_entry = known.
find(type);
708 if(known_entry!=known.end())
709 return known_entry->second;
711 ::std::pair<abstraction_types_mapt::iterator, bool> map_entry(
713 if(!map_entry.second)
714 return map_entry.first->second;
716 if(type.
id() == ID_array || type.
id() == ID_pointer)
729 if(type.
id() == ID_array)
730 map_entry.first->second =
737 else if(type.
id() == ID_struct_tag || type.
id() == ID_union_tag)
743 for(
const auto &comp : struct_union_type.
components())
745 if(comp.get_anonymous())
753 new_comp.back().set_name(comp.get_name());
754 new_comp.back().set_pretty_name(comp.get_pretty_name());
755 new_comp.back().type()=subt;
757 if(!new_comp.empty())
762 const symbolt &existing_tag_symbol =
769 existing_tag_symbol.
mode,
772 abstracted_type_symbol.
is_type =
true;
773 abstracted_type_symbol.
is_lvalue =
false;
778 abstracted_type_symbol.
is_macro =
true;
780 if(type.
id() == ID_struct_tag)
787 return map_entry.first->second;
793 if(abstract_type.
is_nil())
796 if(
object.
id()==ID_typecast)
801 return dest.
type() != abstract_type ||
802 (dest.
type().
id() == ID_array && abstract_type.
id() == ID_pointer &&
807 if(
object.
id()==ID_string_constant)
809 const std::string &str_value =
813 const std::size_t str_len =
814 std::min(str_value.size(), str_value.find(
'\0'));
819 object.
id() == ID_array &&
827 if(
object.
id()==ID_symbol)
830 if(
object.
id()==ID_if)
833 if(
object.
id()==ID_member)
844 if(
object.
id()==ID_dereference)
854 if(
object.
id()==ID_index)
865 if(
object.type().
id()==ID_pointer)
872 exprt &dest,
bool write)
879 if(op1_err && op2_err)
900 exprt &dest,
bool write)
909 const auto size = numeric_cast<mp_integer>(a_size);
911 if(!size.has_value())
914 *size ==
object.operands().size(),
915 "wrong number of array object arguments");
917 exprt::operandst::const_iterator it=
object.operands().begin();
926 exprt &dest,
bool write)
963 return exprt(ID_null_object, type);
985 return exprt(ID_null_object, type);
993 locals[identifier]=identifier;
996 new_symbol.
type=type;
998 new_symbol.
name=identifier;
1001 new_symbol.
mode=ID_C;
1006 return ns.
lookup(identifier).symbol_expr();
1023 identifier = parameter_map_entry->second;
1056 new_symbol.
type=type;
1059 new_symbol.
name=identifier;
1075 dummy_loc->source_location_nonconst() = symbol.
location;
1095 new_symbol.
name=identifier;
1097 new_symbol.
mode=ID_C;
1125 while(lhs.
id() == ID_typecast)
1132 if(lhs.
id()==ID_minus)
1141 while(lhs.
id() == ID_typecast)
1153 const exprt &lhs = target->assign_lhs();
1154 const exprt rhs = target->assign_rhs();
1155 const exprt *rhsp = &(target->assign_rhs());
1157 while(rhsp->
id()==ID_typecast)
1161 if(abstract_type.
is_nil())
1164 exprt new_lhs, new_rhs;
1173 if(lhs.
type().
id()==ID_pointer && !unknown)
1179 target->source_location();
1182 return std::next(target);
1194 const exprt &lhs = target->assign_lhs();
1195 const exprt *rhsp = &(target->assign_rhs());
1197 while(rhsp->
id()==ID_typecast)
1205 if(lhs.
id()==ID_index)
1215 "failed to create length-component for the left-hand-side");
1223 return char_assign(dest, target, new_lhs, i2, min_expr);
1226 else if(lhs.
id()==ID_dereference)
1235 "failed to create length-component for the left-hand-side");
1256 const exprt &new_lhs,
1265 "failed to create is_zero-component for the left-hand-side");
1269 assignment1->code_nonconst().add_source_location() =
1270 target->source_location();
1274 assignment2->code_nonconst().add_source_location() =
1275 target->source_location();
1278 assignment2->code_nonconst().op0(), assignment2->code_nonconst().op1());
1298 if(lhs.
type().
id()==ID_array)
1301 const auto size = numeric_cast<mp_integer>(a_size);
1303 if(!size.has_value())
1310 else if(lhs.
type().
id() == ID_pointer)
1315 else if(lhs.
type().
id()==ID_struct || lhs.
type().
id()==ID_union)
1320 for(
const auto &comp : struct_union_type.
components())
1323 !comp.get_name().empty(),
"struct/union components must have a name");
1351 goto_else->complete_goto(else_target);
1352 goto_out->complete_goto(out_target);
1378 assignment->code_nonconst().add_source_location() =
1379 target->source_location();
1387 assignment->code_nonconst().add_source_location() =
1388 target->source_location();
1396 assignment->code_nonconst().add_source_location() =
1397 target->source_location();
1415 "either the expression is not a string or it is not a pointer to one");
1418 a.
type().
id()==ID_pointer?
Class that provides messages with a built-in verbosity 'level'.
#define Forall_goto_program_instructions(it, program)
#define UNREACHABLE
This should be used to mark dead code.
const componentst & components() const
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
static exprt conditional_cast(const exprt &expr, const typet &type)
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
exprt member(const exprt &a, whatt what)
static typet build_type(whatt what)
exprt build(const exprt &pointer, whatt what, bool write, const source_locationt &)
goto_programt::targett abstract_assign(goto_programt &dest, goto_programt::targett it)
#define Forall_operands(it, expr)
const array_exprt & to_array_expr(const exprt &expr)
Cast an exprt to an array_exprt.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
#define CHECK_RETURN(CONDITION)
The type of an expression, extends irept.
std::vector< parametert > parameterst
bool build_pointer(const exprt &object, exprt &dest, bool write)
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const irept & find(const irep_idt &name) const
abstraction_types_mapt abstraction_types_map
Base type for structs and unions.
typet type
Type of symbol.
Operator to dereference a pointer.
The trinary if-then-else operator.
std::vector< irep_idt > sorted_symbol_names() const
Build and return a lexicographically sorted vector of symbol names from all symbols stored in this sy...
goto_programt::targett abstract(goto_programt &dest, goto_programt::targett it)
const string_constantt & to_string_constant(const exprt &expr)
targett add(instructiont &&instruction)
Adds a given instruction at the end.
const type_with_subtypet & to_type_with_subtype(const typet &type)
The plus expression Associativity is not specified.
Base class for all expressions.
std::vector< componentt > componentst
irep_idt base_name
Base (non-scoped) name.
A struct tag type, i.e., struct_typet with an identifier.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Internally generated symbol table entry.
const typet & build_abstraction_type_rec(const typet &type, const abstraction_types_mapt &known)
function_mapt function_map
goto_instruction_codet & code_nonconst()
Set the code represented by this instruction.
Expression to hold a symbol (variable)
static instructiont make_decl(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
bool is_ptr_string_struct(const typet &type) const
code_typet::parametert add_parameter(const symbolt &fct_symbol, const typet &type, const irep_idt &identifier)
void abstract_function_call(goto_programt::targett it)
const minus_exprt & to_minus_expr(const exprt &expr)
Cast an exprt to a minus_exprt.
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
A union tag type, i.e., union_typet with an identifier.
goto_programt::targett abstract_char_assign(goto_programt &dest, goto_programt::targett it)
goto_programt::targett value_assignments(goto_programt &dest, goto_programt::targett it, const exprt &lhs, const exprt &rhs)
void make_type(exprt &dest, const typet &type)
irep_idt pretty_name
Language-specific display name.
bool is_char_type(const typet &type) const
Struct constructor from list of elements.
const exprt & size() const
typet & type()
Return the type of the expression.
::std::map< typet, typet > abstraction_types_mapt
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
static bool has_string_macros(const exprt &expr)
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Replace all uses of char * by a struct that carries that string, and also the underlying allocation a...
exprt build_unknown(whatt what, bool write)
irep_idt mode
Language mode.
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
const tag_typet & to_tag_type(const typet &type)
Cast a typet to a tag_typet.
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
const std::string & id2string(const irep_idt &d)
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
#define forall_operands(it, expr)
static instructiont make_skip(const source_locationt &l=source_locationt::nil())
void declare_define_locals(goto_programt &dest)
const exprt & struct_op() const
#define PRECONDITION(CONDITION)
const irep_idt & get_identifier() const
Array constructor from single element.
exprt boolean_negate(const exprt &src)
negate a Boolean expression, possibly removing a not_exprt, and swapping false and true
exprt make_val_or_dummy_rec(goto_programt &dest, goto_programt::targett ref_instr, const symbolt &symbol, const typet &source_type)
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
symbol_exprt add_dummy_symbol_and_value(goto_programt &dest, goto_programt::targett ref_instr, const symbolt &symbol, const irep_idt &component_name, const typet &type, const typet &source_type)
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
virtual std::pair< symbolt &, bool > insert(symbolt symbol) override
Author: Diffblue Ltd.
pointer_typet pointer_type(const typet &subtype)
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
void build_new_symbol(const symbolt &symbol, const irep_idt &identifier, const typet &type)
const typet & build_abstraction_type(const typet &type)
const irep_idt & id() const
exprt::operandst argumentst
goto_programt::targett char_assign(goto_programt &dest, goto_programt::targett target, const exprt &new_lhs, const exprt &lhs, const exprt &rhs)
const parameterst & parameters() const
source_locationt & add_source_location()
goto_programt::targett value_assignments_if(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const if_exprt &rhs)
goto_programt initialization
exprt pointer_offset(const exprt &pointer)
int main(int argc, char *argv[])
void clear()
Clear the goto program.
bool build_wrap(const exprt &object, exprt &dest, bool write)
void replace_string_macros(exprt &expr, bool lhs, const source_locationt &)
static bool is_ptr_argument(const typet &type)
void destructive_append(goto_programt &p)
Appends the given program p to *this. p is destroyed.
A side_effect_exprt that returns a non-deterministically chosen value.
void add_str_parameters(symbolt &fct_symbol, goto_functiont::parameter_identifierst ¶meter_identifiers)
bool is_zero() const
Return whether the expression is a constant representing 0.
Extract member of struct or union.
instructionst instructions
The list of instructions in the goto program.
Deprecated expression utility functions.
A collection of goto functions.
exprt value
Initial value of symbol.
goto_programt::targett abstract_pointer_assign(goto_programt &dest, goto_programt::targett it)
Structure type, corresponds to C style structs.
goto_functionst goto_functions
GOTO functions.
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
source_locationt location
Source code location of definition of symbol.
unsigned temporary_counter
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
bool build_symbol_constant(const mp_integer &zero_length, const mp_integer &buf_size, exprt &dest)
#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION,...)
A base class for relations, i.e., binary predicates whose two operands have the same type.
void make_decl_and_def(goto_programt &dest, goto_programt::targett ref_instr, const irep_idt &identifier, const irep_idt &source_sym)
const typet & base_type() const
The type of the data what we point to.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
A generic container class for the GOTO intermediate representation of one function.
const typet & subtype() const
std::vector< irep_idt > parameter_identifierst
bool build_array(const array_exprt &object, exprt &dest, bool write)
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
irep_idt get_component_name() const
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Operator to return the address of an object.
source_locationt & add_source_location()
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
void move_lhs_arithmetic(exprt &lhs, exprt &rhs)
Semantic type conversion.
unsignedbv_typet size_type()
void string_abstraction(goto_modelt &goto_model, message_handlert &message_handler)
A goto_instruction_codet representing an assignment in the program.
The Boolean constant true.
irep_idt module
Name of module the symbol belongs to.
string_abstractiont(goto_modelt &goto_model, message_handlert &_message_handler)
Apply string abstraction to goto_model.
bitvector_typet c_index_type()
bool is_constant(const typet &type)
This method tests, if the given typet is a constant.
bool build_if(const if_exprt &o_if, exprt &dest, bool write)
This class represents an instruction in the GOTO intermediate representation.
message_handlert & message_handler
const source_locationt & source_location() const
symbol_tablet symbol_table
Symbol table.
Array constructor from list of elements.
bool build_symbol(const symbol_exprt &sym, exprt &dest)
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
irep_idt name
The unique identifier.
void swap(goto_programt &program)
Swap the goto program.
instructionst::iterator targett
static instructiont make_incomplete_goto(const exprt &_cond, const source_locationt &l=source_locationt::nil())
const struct_exprt & to_struct_expr(const exprt &expr)
Cast an exprt to a struct_exprt.
goto_programt::targett value_assignments_string_struct(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt &rhs)
const typet & element_type() const
The type of the elements of the array.
const std::string integer2string(const mp_integer &n, unsigned base)