Go to the documentation of this file.
31 const std::string &option,
32 const std::list<std::string> &values)
38 auto const user_min_null_tree_depth =
39 string2optional<std::size_t>(value, 10);
40 if(user_min_null_tree_depth.has_value())
47 "failed to convert '" + value +
"' to integer",
56 auto const user_max_nondet_tree_depth =
57 string2optional<std::size_t>(value, 10);
58 if(user_max_nondet_tree_depth.has_value())
65 "failed to convert '" + value +
"' to integer",
90 [](
const std::string &opt) ->
irep_idt { return irep_idt{opt}; });
95 const auto list_of_members_string =
98 const auto list_of_members =
split_string(list_of_members_string,
',');
99 for(
const auto &member : list_of_members)
101 const auto selection_spec_strings =
split_string(member,
'.');
103 selection_specs.push_back({});
104 auto &selection_spec = selection_specs.back();
106 selection_spec_strings.begin(),
107 selection_spec_strings.end(),
108 std::back_inserter(selection_spec),
109 [](
const std::string &member_name_string) {
110 return irep_idt{member_name_string};
121 : initialization_config(std::move(initialization_config)),
122 goto_model(goto_model),
123 max_depth_var_name(get_fresh_global_name(
126 initialization_config.max_nondet_tree_depth,
128 min_depth_var_name(get_fresh_global_name(
131 initialization_config.min_null_tree_depth,
148 if(selection_spec.front() == lhs_id)
158 if(lhs.
id() == ID_symbol)
160 const auto maybe_cluster_index =
162 if(maybe_cluster_index.has_value())
166 const auto set_equal_case =
175 const auto should_make_equal =
179 should_make_equal, set_equal_case, proper_init_case});
183 body.
add(set_equal_case);
197 if(lhs.
id() == ID_symbol)
203 if(size_var.has_value())
213 const auto &fun_type_params =
216 type_try_dynamic_cast<pointer_typet>(fun_type_params.back().type());
217 INVARIANT(size_var_type,
"Size parameter must have pointer type.");
224 for(
const auto &irep_pair :
228 if(irep_pair.second == lhs_name)
238 const typet &type_to_construct =
247 const exprt &depth_symbol,
251 const bool is_nullable)
255 if(type.
id() == ID_struct_tag)
259 else if(type.
id() == ID_pointer)
270 if(lhs_name.has_value())
281 else if(type.
id() == ID_array)
302 bool is_nullable =
false;
303 bool has_size_param =
false;
304 if(expr.
id() == ID_symbol)
312 has_size_param =
true;
320 const std::string &pretty_type =
type2id(type);
327 depth_parameter.set_identifier(depth_symbol.
name);
328 fun_params.push_back(depth_parameter);
335 fun_params.push_back(result_parameter);
342 if(size_var.has_value())
345 symbol_table.lookup_ref(*size_var).symbol_expr();
354 fun_params.back().set_identifier(size_symbol.
name);
360 symbolt *mutable_symbol = symbol_table.get_writeable(function_symbol.
name);
378 if(malloc_sym ==
nullptr)
389 return malloc_sym->symbol_expr();
437 std::ostringstream out{};
438 out <<
"recursive_initialization_config {"
441 <<
"\n mode = " <<
mode
444 <<
"\n pointers_to_treat_as_arrays = [";
447 out <<
"\n " << pointer;
450 <<
"\n variables_that_hold_array_sizes = [";
453 out <<
"\n " << array_size;
456 out <<
"\n array_name_to_associated_size_variable = [";
457 for(
auto const &associated_array_size :
460 out <<
"\n " << associated_array_size.first <<
" -> "
461 << associated_array_size.second;
464 out <<
"\n pointers_to_treat_as_cstrings = [";
465 for(
const auto &pointer_to_treat_as_string_name :
468 out <<
"\n " << pointer_to_treat_as_string_name << std::endl;
477 const std::string &symbol_base_name,
484 std::move(symbol_type),
498 fresh_symbol.
location = std::move(source_location);
503 const std::string &symbol_name,
504 const exprt &initial_value)
const
511 fresh_symbol.value = initial_value;
512 return fresh_symbol.name;
516 const std::string &symbol_name)
const
524 return fresh_symbol.symbol_expr();
528 const std::string &symbol_name)
const
543 const std::string &symbol_name,
544 const typet &type)
const
559 const std::string &fun_name,
560 const typet &fun_type)
567 function_symbol.
name = function_symbol.base_name =
568 function_symbol.pretty_name = fresh_name;
570 function_symbol.is_lvalue =
true;
572 function_symbol.type = fun_type;
580 const std::string &symbol_name,
581 const typet &symbol_type)
602 return maybe_symbol->symbol_expr();
607 if(type.
id() == ID_struct_tag)
613 else if(type.
id() == ID_pointer)
615 else if(type.
id() == ID_array)
617 const auto array_size =
624 else if(type.
id() == ID_signedbv)
626 else if(type.
id() == ID_unsignedbv)
635 if(free_sym ==
nullptr)
646 return free_sym->symbol_expr();
686 if(has_seen.has_value())
689 should_not_recurse.push_back(has_seen_expr);
698 const auto should_recurse_nondet =
703 should_recurse_nondet};
707 if(has_seen.has_value())
714 seen_assign_prev =
code_assignt{*has_seen, has_seen_prev};
735 if(has_seen.has_value())
737 then_case.add(seen_assign_prev);
753 const auto array_size =
757 for(std::size_t index = 0; index < array_size; index++)
789 if(
component.type().get_bool(ID_C_constant))
797 return std::move(member_expr);
800 initialize(component_initialisation_lhs, depth, body);
859 const typet mutable_dynamic_array_type =
865 for(
auto array_size = min_array_size; array_size <= max_array_size;
910 body.add(
code_fort{for_init, for_cond, for_iter, for_body});
927 expr.
type().
id() != ID_pointer ||
932 if(common_arguments_origin.has_value() && expr.
id() == ID_symbol)
937 return origin_name == expr_name;
951 if(!maybe_cluster_index.has_value())
964 const auto condition =
991 const auto &function_pointer_type =
to_pointer_type(result_type.base_type());
993 const auto &function_type =
to_code_type(function_pointer_type.base_type());
995 std::vector<exprt> targets;
999 if(sym.second.type == function_type)
1010 const auto function_pointer_selector =
1012 body.add(
code_declt{function_pointer_selector});
1013 auto function_pointer_index = std::size_t{0};
1015 for(
const auto &target : targets)
1018 auto const sym_to_lookup =
1019 target.
id() == ID_address_of
1039 if(function_pointer_index != targets.size() - 1)
1042 function_pointer_selector,
1043 from_integer(function_pointer_index, function_pointer_selector.type())};
1051 ++function_pointer_index;
1061 const std::vector<irep_idt> &selection_spec)
1067 auto component_member = lhs;
1070 for(
auto it = selection_spec.begin() + 1; it != selection_spec.end(); it++)
1072 if(component_member.type().id() != ID_struct_tag)
1075 "'" +
id2string(*it) +
"' is not a component name",
1079 const auto &struct_type =
to_struct_type(ns.follow_tag(struct_tag_type));
1082 for(
auto const &
component : struct_type.components())
1084 const auto &component_type =
component.type();
1085 const auto component_name =
component.get_name();
1087 if(*it == component_name)
1090 member_exprt{component_member, component_name, component_type};
1098 "'" +
id2string(*it) +
"' is not a component name",
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
std::set< irep_idt > pointers_to_treat_as_cstrings
std::string array_name(const namespacet &ns, const exprt &expr)
A codet representing sequential composition of program statements.
static exprt conditional_cast(const exprt &expr, const typet &type)
#define COMMON_HARNESS_GENERATOR_FUNCTION_POINTER_CAN_BE_NULL_OPT
symbol_exprt get_fresh_local_typed_symexpr(const std::string &symbol_name, const typet &type) const
Construct a new local symbol of type type initialised to init_value.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
exprt conjunction(const exprt::operandst &op)
1) generates a conjunction for two or more operands 2) for one operand, returns the operand 3) return...
irep_idt min_depth_var_name
code_blockt build_array_constructor(const exprt &depth, const symbol_exprt &result)
Constructor for arrays: simply iterates over elements and initialise each one.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
symbol_exprt get_symbol_expr(const irep_idt &symbol_name) const
Recover the symbol expression from symbol table.
irep_idt get_new_name(const irep_idt &name, const namespacet &ns, char delimiter)
Build and identifier not yet present in the namespace ns based on name.
codet representation of a for statement.
#define CHECK_RETURN(CONDITION)
The type of an expression, extends irept.
std::vector< parametert > parameterst
irep_idt build_constructor(const exprt &expr)
Check if a constructor for the type of expr already exists and create it if not.
static abstract_object_pointert transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns)
void initialize_selected_member(const exprt &lhs, const exprt &depth, code_blockt &body, const std::vector< irep_idt > &selection_spec)
Select the specified struct-member to be non-deterministically initialized.
typet type
Type of symbol.
symbol_exprt get_malloc_function()
Get the malloc function as symbol exprt, and inserts it into the goto-model if it doesn't exist alrea...
Operator to dereference a pointer.
optionalt< irep_idt > get_associated_size_variable(const irep_idt &array_name) const
symbol_exprt get_fresh_local_symexpr(const std::string &symbol_name) const
Construct a new local symbol of type int initialised to 0.
#define COMMON_HARNESS_GENERATOR_HAVOC_MEMBER_OPT
void replace(const union_find_replacet &replace_map, string_not_contains_constraintt &constraint)
A goto_instruction_codet representing the declaration of a local variable.
#define FILE_LOCAL_PREFIX
The plus expression Associativity is not specified.
std::map< irep_idt, irep_idt > array_name_to_associated_array_size_variable
Base class for all expressions.
irep_idt base_name
Base (non-scoped) name.
std::vector< std::vector< irep_idt > > selection_specs
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
std::string require_exactly_one_value(const std::string &option, const std::list< std::string > &values)
Returns the only value of a single element list, throws an exception if not passed a single element l...
Expression to hold a symbol (variable)
void free_cluster_origins(code_blockt &body)
bool is_array_size_parameter(const irep_idt &cmdline_arg) const
void initialize(const exprt &lhs, const exprt &depth, code_blockt &body)
Generate initialisation code for lhs into body.
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
optionalt< equal_cluster_idt > find_equal_cluster(const irep_idt &name) const
codet representation of an if-then-else statement.
code_blockt build_function_pointer_constructor(const symbol_exprt &result, bool is_nullable)
Constructor for function pointers.
irep_idt pretty_name
Language-specific display name.
std::set< irep_idt > pointers_to_treat_as_arrays
bool should_be_treated_as_array(const irep_idt &pointer_name) const
const exprt & size() const
typet remove_const(typet type)
Remove const qualifier from type (if any).
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool needs_freeing(const exprt &expr) const
std::size_t max_nondet_tree_depth
symbolt & get_fresh_param_symbol(const std::string ¶m_name, const typet ¶m_type)
Construct a new parameter symbol of type param_type.
typet & type()
Return the type of the expression.
code_blockt build_null_pointer(const symbol_exprt &result_symbol)
goto_instruction_codet representation of a function call statement.
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)
bool can_cast_type< code_typet >(const typet &type)
Check whether a reference to a typet is a code_typet.
std::size_t max_dynamic_array_size
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
exprt disjunction(const exprt::operandst &op)
1) generates a disjunction for two or more operands 2) for one operand, returns the operand 3) return...
static symbolt result_symbol(const irep_idt &identifier, const typet &type, const source_locationt &source_location, symbol_tablet &symbol_table)
irep_idt mode
Language mode.
signedbv_typet signed_int_type()
bool has_prefix(const std::string &s, const std::string &prefix)
code_blockt build_pointer_constructor(const exprt &depth, const symbol_exprt &result)
Generic constructor for all pointers: only builds one pointee (not an array) but may recourse in case...
bool arguments_may_be_equal
The null pointer constant.
const std::string & id2string(const irep_idt &d)
std::unordered_set< irep_idt > potential_null_function_pointers
bool can_cast_type< struct_tag_typet >(const typet &type)
Check whether a reference to a typet is a struct_tag_typet.
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)
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly two argu...
#define PRECONDITION(CONDITION)
symbol_exprt get_fresh_global_symexpr(const std::string &symbol_name) const
Construct a new global symbol of type int initialised to 0.
type_constructor_namest type_constructor_names
const irep_idt & get_identifier() const
auto optional_lookup(const map_like_collectiont &map, const keyt &key) -> optionalt< decltype(map.find(key) ->second)>
Lookup a key in a map, if found return the associated value, nullopt otherwise.
An assumption, which must hold in subsequent code.
void set_file(const irep_idt &file)
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
code_blockt build_dynamic_array_constructor(const exprt &depth, const symbol_exprt &result, const exprt &size, const optionalt< irep_idt > &lhs_name)
Constructor for dynamic arrays: allocate memory for n elements (n is random but bounded) and initiali...
Binary multiplication Associativity is not specified.
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.
const irep_idt & id() const
#define COMMON_HARNESS_GENERATOR_MAX_NONDET_TREE_DEPTH_OPT
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::vector< exprt > operandst
void add(const codet &code)
recursive_initializationt(recursive_initialization_configt initialization_config, goto_modelt &goto_model)
#define GOTO_HARNESS_PREFIX
const symbolt & get_fresh_fun_symbol(const std::string &fun_name, const typet &fun_type)
Construct a new function symbol of type fun_type.
const parameterst & parameters() const
irep_idt get_fresh_global_name(const std::string &symbol_name, const exprt &initial_value) const
Construct a new global symbol of type int and set it's value to initial_value.
nonstd::optional< T > optionalt
std::vector< optionalt< exprt > > common_arguments_origins
bool handle_option(const std::string &option, const std::list< std::string > &values)
Parse the options specific for recursive initialisation.
bitvector_typet char_type()
codet representation of a "return from a function" statement.
code_blockt build_constructor_body(const exprt &depth_symbol, const symbol_exprt &result_symbol, const optionalt< exprt > &size_symbol, const optionalt< irep_idt > &lhs_name, const bool is_nullable)
Case analysis for which constructor should be used.
void free_if_possible(const exprt &expr, code_blockt &body)
std::set< irep_idt > variables_that_hold_array_sizes
bool should_be_treated_as_cstring(const irep_idt &pointer_name) const
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
Extract member of struct or union.
exprt value
Initial value of symbol.
irept & add(const irep_idt &name)
std::string type2id(const typet &type) const
Simple pretty-printer for typet.
source_locationt location
Source code location of definition of symbol.
#define COMMON_HARNESS_GENERATOR_MIN_ARRAY_SIZE_OPT
std::size_t min_dynamic_array_size
symbol_exprt get_free_function()
Get the free function as symbol expression, and inserts it into the goto-model if it doesn't exist al...
std::size_t require_one_size_value(const std::string &option, const std::list< std::string > &values)
Returns the only Nat value of a single element list, throws an exception if not passed a single eleme...
const symbol_tablet & get_symbol_table() const override
Accessor to get the symbol table.
A base class for relations, i.e., binary predicates whose two operands have the same type.
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.
std::size_t min_null_tree_depth
std::size_t equal_cluster_idt
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
code_blockt build_nondet_constructor(const symbol_exprt &result) const
Default constructor: assigns non-deterministic value of the right type.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
#define COMMON_HARNESS_GENERATOR_MIN_NULL_TREE_DEPTH_OPT
static symbolt & get_fresh_global_symbol(symbol_tablet &symbol_table, const std::string &symbol_base_name, typet symbol_type, irep_idt mode)
Operator to return the address of an object.
Semantic type conversion.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
unsignedbv_typet size_type()
#define COMMON_HARNESS_GENERATOR_MAX_ARRAY_SIZE_OPT
A goto_instruction_codet representing an assignment in the program.
std::string to_string() const
irep_idt module
Name of module the symbol belongs to.
const recursive_initialization_configt initialization_config
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
symbol_tablet symbol_table
Symbol table.
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.
Mangle names of file-local functions to make them unique.
irep_idt max_depth_var_name
An expression containing a side effect.
std::vector< std::set< irep_idt > > pointers_to_treat_equal
code_blockt build_struct_constructor(const exprt &depth, const symbol_exprt &result)
Constructor for structures: simply iterates over members and initialise each one.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.