CBMC
allocate_objects.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "allocate_objects.h"
10 
11 #include <util/c_types.h>
12 #include <util/fresh_symbol.h>
13 #include <util/pointer_expr.h>
15 #include <util/symbol.h>
16 
17 #include "goto_instruction_code.h"
18 
35  code_blockt &assignments,
36  const exprt &target_expr,
37  const typet &allocate_type,
38  const lifetimet lifetime,
39  const irep_idt &basename_prefix)
40 {
41  switch(lifetime)
42  {
45  assignments, target_expr, allocate_type, basename_prefix);
46  break;
47 
50  assignments, target_expr, allocate_type, basename_prefix);
51  break;
52 
53  case lifetimet::DYNAMIC:
54  return allocate_dynamic_object(assignments, target_expr, allocate_type);
55  break;
56  }
57 
59 }
60 
73  code_blockt &assignments,
74  const exprt &target_expr,
75  const typet &allocate_type,
76  const irep_idt &basename_prefix)
77 {
79  assignments, target_expr, allocate_type, false, basename_prefix);
80 }
81 
94  code_blockt &assignments,
95  const exprt &target_expr,
96  const typet &allocate_type,
97  const irep_idt &basename_prefix)
98 {
100  assignments, target_expr, allocate_type, true, basename_prefix);
101 }
102 
110  const typet &allocate_type,
111  const irep_idt &basename_prefix)
112 {
113  symbolt &aux_symbol = get_fresh_aux_symbol(
114  allocate_type,
116  id2string(basename_prefix),
118  symbol_mode,
119  symbol_table);
120 
121  add_created_symbol(aux_symbol);
122 
123  return aux_symbol.symbol_expr();
124 }
125 
127  code_blockt &output_code,
128  const exprt &target_expr,
129  const typet &allocate_type)
130 {
131  if(allocate_type.id() == ID_empty)
132  {
133  // make null
135  target_expr,
136  null_pointer_exprt{to_pointer_type(target_expr.type())},
138  output_code.add(std::move(code));
139 
140  return exprt();
141  }
142 
143  // build size expression
144  auto object_size = size_of_expr(allocate_type, ns);
145  INVARIANT(object_size.has_value(), "Size of objects should be known");
146 
147  // create a symbol for the malloc expression so we can initialize
148  // without having to do it potentially through a double-deref, which
149  // breaks the to-SSA phase.
150  symbolt &malloc_sym = get_fresh_aux_symbol(
151  pointer_type(allocate_type),
153  "malloc_site",
155  symbol_mode,
156  symbol_table);
157 
158  add_created_symbol(malloc_sym);
159 
160  code_frontend_assignt assign =
161  make_allocate_code(malloc_sym.symbol_expr(), object_size.value());
162  output_code.add(assign);
163 
164  exprt malloc_symbol_expr = typecast_exprt::conditional_cast(
165  malloc_sym.symbol_expr(), target_expr.type());
166 
167  code_frontend_assignt code(target_expr, malloc_symbol_expr);
169  output_code.add(code);
170 
171  return malloc_sym.symbol_expr();
172 }
173 
175  code_blockt &output_code,
176  const exprt &target_expr,
177  const typet &allocate_type)
178 {
179  return dereference_exprt(
180  allocate_dynamic_object_symbol(output_code, target_expr, allocate_type));
181 }
182 
184  code_blockt &assignments,
185  const exprt &target_expr,
186  const typet &allocate_type,
187  const bool static_lifetime,
188  const irep_idt &basename_prefix)
189 {
190  symbolt &aux_symbol = get_fresh_aux_symbol(
191  allocate_type,
193  id2string(basename_prefix),
195  symbol_mode,
196  symbol_table);
197 
198  aux_symbol.is_static_lifetime = static_lifetime;
199  add_created_symbol(aux_symbol);
200 
202  address_of_exprt(aux_symbol.symbol_expr()), target_expr.type());
203 
204  code_frontend_assignt code(target_expr, aoe);
206  assignments.add(code);
207 
208  if(aoe.id() == ID_typecast)
209  {
210  return dereference_exprt(aoe);
211  }
212  else
213  {
214  return aux_symbol.symbol_expr();
215  }
216 }
217 
222 {
223  symbols_created.push_back(symbol.name);
224 }
225 
230 {
231  // Add the following code to init_code for each symbol that's been created:
232  // <type> <identifier>;
233  for(const auto &symbol_id : symbols_created)
234  {
235  const symbolt &symbol = ns.lookup(symbol_id);
236  if(!symbol.is_static_lifetime)
237  {
238  code_frontend_declt decl{symbol.symbol_expr()};
240  init_code.add(decl);
241  }
242  }
243 }
244 
249 {
250  // Add the following code to init_code for each symbol that's been created:
251  // INPUT("<identifier>", <identifier>);
252  for(const auto &symbol_id : symbols_created)
253  {
254  const symbolt &symbol = ns.lookup(symbol_id);
255  init_code.add(
256  code_inputt{symbol.base_name, symbol.symbol_expr(), source_location});
257  }
258 }
259 
261 make_allocate_code(const symbol_exprt &lhs, const exprt &size)
262 {
263  side_effect_exprt alloc{
264  ID_allocate, {size, false_exprt()}, lhs.type(), lhs.source_location()};
265  return code_frontend_assignt(lhs, alloc);
266 }
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
code_blockt
A codet representing sequential composition of program statements.
Definition: std_code.h:129
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
goto_instruction_code.h
lifetimet::AUTOMATIC_LOCAL
@ AUTOMATIC_LOCAL
Allocate local objects with automatic lifetime.
typet
The type of an expression, extends irept.
Definition: type.h:28
fresh_symbol.h
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
code_frontend_declt
A codet representing the declaration of a local variable.
Definition: std_code.h:346
exprt
Base class for all expressions.
Definition: expr.h:55
symbolt::base_name
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
allocate_objectst::symbol_table
symbol_table_baset & symbol_table
Definition: allocate_objects.h:104
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
allocate_objectst::symbol_mode
const irep_idt symbol_mode
Definition: allocate_objects.h:100
make_allocate_code
code_frontend_assignt make_allocate_code(const symbol_exprt &lhs, const exprt &size)
Create code allocating an object of size size and assigning it to lhs
Definition: allocate_objects.cpp:261
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
allocate_objectst::add_created_symbol
void add_created_symbol(const symbolt &symbol)
Add a pointer to a symbol to the list of pointers to symbols created so far.
Definition: allocate_objects.cpp:221
allocate_objectst::ns
const namespacet ns
Definition: allocate_objects.h:105
null_pointer_exprt
The null pointer constant.
Definition: pointer_expr.h:734
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
allocate_objectst::allocate_dynamic_object_symbol
exprt allocate_dynamic_object_symbol(code_blockt &output_code, const exprt &target_expr, const typet &allocate_type)
Generates code for allocating a dynamic object.
Definition: allocate_objects.cpp:126
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
pointer_expr.h
allocate_objectst::allocate_static_global_object
exprt allocate_static_global_object(code_blockt &assignments, const exprt &target_expr, const typet &allocate_type, const irep_idt &basename_prefix="tmp")
Creates a global variable with static lifetime.
Definition: allocate_objects.cpp:93
allocate_objectst::allocate_object
exprt allocate_object(code_blockt &assignments, const exprt &target_expr, const typet &allocate_type, const lifetimet lifetime, const irep_idt &basename_prefix="tmp")
Allocates a new object, either by creating a local variable with automatic lifetime,...
Definition: allocate_objects.cpp:34
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
code_frontend_assignt
A codet representing an assignment in the program.
Definition: std_code.h:23
symbol.h
Symbol table entry.
object_size
exprt object_size(const exprt &pointer)
Definition: pointer_predicates.cpp:33
irept::id
const irep_idt & id() const
Definition: irep.h:396
code_blockt::add
void add(const codet &code)
Definition: std_code.h:168
false_exprt
The Boolean constant false.
Definition: std_expr.h:3016
allocate_objectst::name_prefix
const irep_idt name_prefix
Definition: allocate_objects.h:102
allocate_objectst::declare_created_symbols
void declare_created_symbols(code_blockt &init_code)
Adds declarations for all non-static symbols created.
Definition: allocate_objects.cpp:229
lifetimet
lifetimet
Selects the kind of objects allocated.
Definition: allocate_objects.h:16
allocate_objectst::source_location
const source_locationt source_location
Definition: allocate_objects.h:101
allocate_objectst::allocate_non_dynamic_object
exprt allocate_non_dynamic_object(code_blockt &assignments, const exprt &target_expr, const typet &allocate_type, const bool static_lifetime, const irep_idt &basename_prefix)
Definition: allocate_objects.cpp:183
code_inputt
A goto_instruction_codet representing the declaration that an input of a particular description has a...
Definition: goto_instruction_code.h:407
symbolt
Symbol table entry.
Definition: symbol.h:27
lifetimet::STATIC_GLOBAL
@ STATIC_GLOBAL
Allocate global objects with static lifetime.
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
lifetimet::DYNAMIC
@ DYNAMIC
Allocate dynamic objects (using ALLOCATE)
size_of_expr
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:280
allocate_objectst::allocate_dynamic_object
exprt allocate_dynamic_object(code_blockt &output_code, const exprt &target_expr, const typet &allocate_type)
Generate the same code as allocate_dynamic_object_symbol, but return a dereference_exprt that derefer...
Definition: allocate_objects.cpp:174
allocate_objectst::mark_created_symbols_as_input
void mark_created_symbols_as_input(code_blockt &init_code)
Adds code to mark the created symbols as input.
Definition: allocate_objects.cpp:248
allocate_objectst::symbols_created
std::vector< irep_idt > symbols_created
Definition: allocate_objects.h:107
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:370
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:216
allocate_objectst::allocate_automatic_local_object
exprt allocate_automatic_local_object(code_blockt &assignments, const exprt &target_expr, const typet &allocate_type, const irep_idt &basename_prefix="tmp")
Creates a local variable with automatic lifetime.
Definition: allocate_objects.cpp:72
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
allocate_objects.h
c_types.h
get_fresh_aux_symbol
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 ...
Definition: fresh_symbol.cpp:32
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
side_effect_exprt
An expression containing a side effect.
Definition: std_code.h:1449
validation_modet::INVARIANT
@ INVARIANT