CBMC
recursive_initialization.h
Go to the documentation of this file.
1 /******************************************************************\
2 
3 Module: recursive_initialization
4 
5 Author: Diffblue Ltd.
6 
7 \******************************************************************/
8 
9 #ifndef CPROVER_GOTO_HARNESS_RECURSIVE_INITIALIZATION_H
10 #define CPROVER_GOTO_HARNESS_RECURSIVE_INITIALIZATION_H
11 
12 #include <map>
13 #include <set>
14 #include <unordered_set>
15 
16 #include <util/cprover_prefix.h>
17 #include <util/optional.h>
18 #include <util/prefix.h>
19 #include <util/std_expr.h>
20 #include <util/symbol.h>
21 
22 class code_blockt;
23 class goto_modelt;
24 
25 #define GOTO_HARNESS_PREFIX "__GOTO_HARNESS"
27 {
28  std::size_t min_null_tree_depth = 1;
29  std::size_t max_nondet_tree_depth = 2;
31  std::unordered_set<irep_idt> potential_null_function_pointers;
32 
33  // array stuff
34  std::size_t max_dynamic_array_size = 2;
35  std::size_t min_dynamic_array_size = 1;
36 
37  std::set<irep_idt> pointers_to_treat_as_arrays;
38  std::set<irep_idt> variables_that_hold_array_sizes;
39  std::map<irep_idt, irep_idt> array_name_to_associated_array_size_variable;
40 
41  std::set<irep_idt> pointers_to_treat_as_cstrings;
42  std::vector<std::set<irep_idt>> pointers_to_treat_equal;
43 
44  bool arguments_may_be_equal = false;
45 
46  std::vector<std::vector<irep_idt>> selection_specs;
47 
48  std::string to_string() const; // for debugging purposes
49 
55  bool handle_option(
56  const std::string &option,
57  const std::list<std::string> &values);
58 };
59 
63 {
64 public:
65  using recursion_sett = std::set<irep_idt>;
66  using equal_cluster_idt = std::size_t;
68  {
72  bool operator<(const constructor_keyt &other) const
73  {
75  std::tie(
76  other.constructor_type,
77  other.is_nullable,
78  other.has_size_parameter);
79  };
80  bool operator==(const constructor_keyt &other) const
81  {
82  return std::tie(constructor_type, is_nullable, has_size_parameter) ==
83  std::tie(
84  other.constructor_type,
85  other.is_nullable,
86  other.has_size_parameter);
87  };
88  };
89  using type_constructor_namest = std::map<constructor_keyt, irep_idt>;
90 
94 
99  void initialize(const exprt &lhs, const exprt &depth, code_blockt &body);
100 
105 
106  static bool is_initialization_allowed(const symbolt &symbol)
107  {
108  auto const symbol_name = id2string(symbol.name);
109  return (
110  symbol.is_static_lifetime && symbol.is_lvalue &&
111  !symbol.type.get_bool(ID_C_constant) && symbol.type.id() != ID_code &&
112  !has_prefix(symbol_name, CPROVER_PREFIX) &&
113  !has_prefix(symbol_name, GOTO_HARNESS_PREFIX));
114  }
115 
116  bool needs_freeing(const exprt &expr) const;
117  void free_if_possible(const exprt &expr, code_blockt &body);
118  void free_cluster_origins(code_blockt &body);
119 
120 private:
126  std::vector<optionalt<exprt>> common_arguments_origins;
127 
132 
133  bool should_be_treated_as_array(const irep_idt &pointer_name) const;
135  bool is_array_size_parameter(const irep_idt &cmdline_arg) const;
138  bool should_be_treated_as_cstring(const irep_idt &pointer_name) const;
139 
147  const std::string &symbol_name,
148  const exprt &initial_value) const;
149 
153  symbol_exprt get_fresh_global_symexpr(const std::string &symbol_name) const;
154 
158  symbol_exprt get_fresh_local_symexpr(const std::string &symbol_name) const;
159 
165  const std::string &symbol_name,
166  const typet &type) const;
167 
172  const symbolt &
173  get_fresh_fun_symbol(const std::string &fun_name, const typet &fun_type);
174 
180  const std::string &param_name,
181  const typet &param_type);
182 
186  symbol_exprt get_symbol_expr(const irep_idt &symbol_name) const;
187 
192  std::string type2id(const typet &type) const;
193 
202  const exprt &depth_symbol,
204  const optionalt<exprt> &size_symbol,
205  const optionalt<irep_idt> &lhs_name,
206  const bool is_nullable);
207 
212  irep_idt build_constructor(const exprt &expr);
213 
219  const symbol_exprt &result,
220  bool is_nullable);
221 
229  build_pointer_constructor(const exprt &depth, const symbol_exprt &result);
230 
237  build_struct_constructor(const exprt &depth, const symbol_exprt &result);
238 
243 
250  build_array_constructor(const exprt &depth, const symbol_exprt &result);
251 
260  const exprt &depth,
261  const symbol_exprt &result,
262  const exprt &size,
263  const optionalt<irep_idt> &lhs_name);
264 
273  const exprt &lhs,
274  const exprt &depth,
275  code_blockt &body,
276  const std::vector<irep_idt> &selection_spec);
277 };
278 
279 #endif // CPROVER_GOTO_HARNESS_RECURSIVE_INITIALIZATION_H
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
recursive_initialization_configt::pointers_to_treat_as_cstrings
std::set< irep_idt > pointers_to_treat_as_cstrings
Definition: recursive_initialization.h:41
array_name
std::string array_name(const namespacet &ns, const exprt &expr)
Definition: array_name.cpp:19
code_blockt
A codet representing sequential composition of program statements.
Definition: std_code.h:129
recursive_initializationt::get_fresh_local_typed_symexpr
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.
Definition: recursive_initialization.cpp:542
recursive_initializationt::min_depth_var_name
irep_idt min_depth_var_name
Definition: recursive_initialization.h:124
recursive_initializationt::constructor_keyt::is_nullable
bool is_nullable
Definition: recursive_initialization.h:70
recursive_initializationt::build_array_constructor
code_blockt build_array_constructor(const exprt &depth, const symbol_exprt &result)
Constructor for arrays: simply iterates over elements and initialise each one.
Definition: recursive_initialization.cpp:745
recursive_initializationt::goto_model
goto_modelt & goto_model
Definition: recursive_initialization.h:122
recursive_initializationt::constructor_keyt::operator==
bool operator==(const constructor_keyt &other) const
Definition: recursive_initialization.h:80
recursive_initializationt::get_symbol_expr
symbol_exprt get_symbol_expr(const irep_idt &symbol_name) const
Recover the symbol expression from symbol table.
Definition: recursive_initialization.cpp:598
typet
The type of an expression, extends irept.
Definition: type.h:28
recursive_initializationt::build_constructor
irep_idt build_constructor(const exprt &expr)
Check if a constructor for the type of expr already exists and create it if not.
Definition: recursive_initialization.cpp:291
recursive_initializationt::initialize_selected_member
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.
Definition: recursive_initialization.cpp:1057
optional.h
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
recursive_initializationt
Class for generating initialisation code for compound structures.
Definition: recursive_initialization.h:62
recursive_initializationt::get_malloc_function
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...
Definition: recursive_initialization.cpp:375
recursive_initializationt::get_associated_size_variable
optionalt< irep_idt > get_associated_size_variable(const irep_idt &array_name) const
Definition: recursive_initialization.cpp:420
recursive_initializationt::get_fresh_local_symexpr
symbol_exprt get_fresh_local_symexpr(const std::string &symbol_name) const
Construct a new local symbol of type int initialised to 0.
Definition: recursive_initialization.cpp:527
prefix.h
recursive_initializationt::constructor_keyt::constructor_type
typet constructor_type
Definition: recursive_initialization.h:69
recursive_initializationt::type_constructor_namest
std::map< constructor_keyt, irep_idt > type_constructor_namest
Definition: recursive_initialization.h:89
recursive_initialization_configt::array_name_to_associated_array_size_variable
std::map< irep_idt, irep_idt > array_name_to_associated_array_size_variable
Definition: recursive_initialization.h:39
exprt
Base class for all expressions.
Definition: expr.h:55
goto_modelt
Definition: goto_model.h:25
recursive_initialization_configt::selection_specs
std::vector< std::vector< irep_idt > > selection_specs
Definition: recursive_initialization.h:46
recursive_initializationt::constructor_keyt::has_size_parameter
bool has_size_parameter
Definition: recursive_initialization.h:71
recursive_initialization_configt::mode
irep_idt mode
Definition: recursive_initialization.h:30
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
recursive_initializationt::free_cluster_origins
void free_cluster_origins(code_blockt &body)
Definition: recursive_initialization.cpp:976
recursive_initializationt::is_array_size_parameter
bool is_array_size_parameter(const irep_idt &cmdline_arg) const
Definition: recursive_initialization.cpp:412
recursive_initializationt::initialize
void initialize(const exprt &lhs, const exprt &depth, code_blockt &body)
Generate initialisation code for lhs into body.
Definition: recursive_initialization.cpp:138
recursive_initializationt::find_equal_cluster
optionalt< equal_cluster_idt > find_equal_cluster(const irep_idt &name) const
Definition: recursive_initialization.cpp:400
recursive_initializationt::recursion_sett
std::set< irep_idt > recursion_sett
Definition: recursive_initialization.h:65
recursive_initializationt::build_function_pointer_constructor
code_blockt build_function_pointer_constructor(const symbol_exprt &result, bool is_nullable)
Constructor for function pointers.
Definition: recursive_initialization.cpp:984
recursive_initializationt::constructor_keyt
Definition: recursive_initialization.h:67
recursive_initialization_configt::pointers_to_treat_as_arrays
std::set< irep_idt > pointers_to_treat_as_arrays
Definition: recursive_initialization.h:37
recursive_initializationt::should_be_treated_as_array
bool should_be_treated_as_array(const irep_idt &pointer_name) const
Definition: recursive_initialization.cpp:392
recursive_initializationt::needs_freeing
bool needs_freeing(const exprt &expr) const
Definition: recursive_initialization.cpp:924
recursive_initialization_configt::max_nondet_tree_depth
std::size_t max_nondet_tree_depth
Definition: recursive_initialization.h:29
recursive_initializationt::get_fresh_param_symbol
symbolt & get_fresh_param_symbol(const std::string &param_name, const typet &param_type)
Construct a new parameter symbol of type param_type.
Definition: recursive_initialization.cpp:579
recursive_initialization_configt::max_dynamic_array_size
std::size_t max_dynamic_array_size
Definition: recursive_initialization.h:34
result_symbol
static symbolt result_symbol(const irep_idt &identifier, const typet &type, const source_locationt &source_location, symbol_tablet &symbol_table)
Definition: c_typecheck_gcc_polymorphic_builtins.cpp:609
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
recursive_initializationt::build_pointer_constructor
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...
Definition: recursive_initialization.cpp:649
recursive_initialization_configt::arguments_may_be_equal
bool arguments_may_be_equal
Definition: recursive_initialization.h:44
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
recursive_initialization_configt::potential_null_function_pointers
std::unordered_set< irep_idt > potential_null_function_pointers
Definition: recursive_initialization.h:31
recursive_initializationt::get_fresh_global_symexpr
symbol_exprt get_fresh_global_symexpr(const std::string &symbol_name) const
Construct a new global symbol of type int initialised to 0.
Definition: recursive_initialization.cpp:515
recursive_initializationt::type_constructor_names
type_constructor_namest type_constructor_names
Definition: recursive_initialization.h:125
recursive_initializationt::build_dynamic_array_constructor
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...
Definition: recursive_initialization.cpp:817
symbol.h
Symbol table entry.
irept::id
const irep_idt & id() const
Definition: irep.h:396
recursive_initializationt::recursive_initializationt
recursive_initializationt(recursive_initialization_configt initialization_config, goto_modelt &goto_model)
Definition: recursive_initialization.cpp:118
GOTO_HARNESS_PREFIX
#define GOTO_HARNESS_PREFIX
Definition: recursive_initialization.h:25
recursive_initializationt::get_fresh_fun_symbol
const symbolt & get_fresh_fun_symbol(const std::string &fun_name, const typet &fun_type)
Construct a new function symbol of type fun_type.
Definition: recursive_initialization.cpp:558
cprover_prefix.h
recursive_initializationt::get_fresh_global_name
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.
Definition: recursive_initialization.cpp:502
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
recursive_initializationt::common_arguments_origins
std::vector< optionalt< exprt > > common_arguments_origins
Definition: recursive_initialization.h:126
recursive_initialization_configt::handle_option
bool handle_option(const std::string &option, const std::list< std::string > &values)
Parse the options specific for recursive initialisation.
Definition: recursive_initialization.cpp:30
recursive_initializationt::build_constructor_body
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.
Definition: recursive_initialization.cpp:246
recursive_initializationt::free_if_possible
void free_if_possible(const exprt &expr, code_blockt &body)
Definition: recursive_initialization.cpp:943
recursive_initializationt::constructor_keyt::operator<
bool operator<(const constructor_keyt &other) const
Definition: recursive_initialization.h:72
recursive_initialization_configt::variables_that_hold_array_sizes
std::set< irep_idt > variables_that_hold_array_sizes
Definition: recursive_initialization.h:38
recursive_initializationt::should_be_treated_as_cstring
bool should_be_treated_as_cstring(const irep_idt &pointer_name) const
Definition: recursive_initialization.cpp:428
recursive_initializationt::type2id
std::string type2id(const typet &type) const
Simple pretty-printer for typet.
Definition: recursive_initialization.cpp:605
recursive_initialization_configt::min_dynamic_array_size
std::size_t min_dynamic_array_size
Definition: recursive_initialization.h:35
symbolt
Symbol table entry.
Definition: symbol.h:27
recursive_initializationt::get_free_function
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...
Definition: recursive_initialization.cpp:632
CPROVER_PREFIX
#define CPROVER_PREFIX
Definition: cprover_prefix.h:14
recursive_initialization_configt
Definition: recursive_initialization.h:26
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
recursive_initialization_configt::min_null_tree_depth
std::size_t min_null_tree_depth
Definition: recursive_initialization.h:28
recursive_initializationt::equal_cluster_idt
std::size_t equal_cluster_idt
Definition: recursive_initialization.h:66
recursive_initializationt::build_nondet_constructor
code_blockt build_nondet_constructor(const symbol_exprt &result) const
Default constructor: assigns non-deterministic value of the right type.
Definition: recursive_initialization.cpp:805
symbolt::is_lvalue
bool is_lvalue
Definition: symbol.h:66
recursive_initialization_configt::to_string
std::string to_string() const
Definition: recursive_initialization.cpp:435
recursive_initializationt::is_initialization_allowed
static bool is_initialization_allowed(const symbolt &symbol)
Definition: recursive_initialization.h:106
recursive_initializationt::initialization_config
const recursive_initialization_configt initialization_config
Definition: recursive_initialization.h:121
std_expr.h
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
recursive_initializationt::max_depth_var_name
irep_idt max_depth_var_name
Definition: recursive_initialization.h:123
irept::get_bool
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
recursive_initialization_configt::pointers_to_treat_equal
std::vector< std::set< irep_idt > > pointers_to_treat_equal
Definition: recursive_initialization.h:42
recursive_initializationt::build_struct_constructor
code_blockt build_struct_constructor(const exprt &depth, const symbol_exprt &result)
Constructor for structures: simply iterates over members and initialise each one.
Definition: recursive_initialization.cpp:767