CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
c_nondet_symbol_factory.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: C Nondet Symbol Factory
4
5Author: Diffblue Ltd.
6
7\*******************************************************************/
8
11
13
14#include <util/arith_tools.h>
15#include <util/c_types.h>
16#include <util/fresh_symbol.h>
17#include <util/namespace.h>
18#include <util/nondet_bool.h>
19#include <util/pointer_expr.h>
20#include <util/std_expr.h>
21#include <util/symbol.h>
22
24
25#include "allocate_objects.h"
27
38 code_blockt &assignments,
39 const exprt &expr,
40 const std::size_t depth,
41 recursion_sett recursion_set,
42 const bool assign_const)
43{
44 const typet &type = expr.type();
45
47 {
48 return;
49 }
50
51 if(type.id()==ID_pointer)
52 {
53 // dereferenced type
55 const typet &base_type = pointer_type.base_type();
56
57 if(base_type.id() == ID_code)
58 {
59 // Handle the pointer-to-code case separately:
60 // leave as nondet_ptr to allow `remove_function_pointers`
61 // to replace the pointer.
62 assignments.add(code_frontend_assignt{
64 return;
65 }
66
67 if(base_type.id() == ID_struct_tag)
68 {
69 const irep_idt struct_tag =
70 to_struct_tag_type(base_type).get_identifier();
71
72 if(
73 recursion_set.find(struct_tag) != recursion_set.end() &&
74 depth >= object_factory_params.max_nondet_tree_depth)
75 {
76 assignments.add(
78
79 return;
80 }
81 }
82
84
85 typet object_type = base_type;
86 if(object_type.id() == ID_empty)
87 object_type = char_type();
88
90 non_null_inst, expr, object_type, lifetime);
91
92 gen_nondet_init(non_null_inst, init_expr, depth + 1, recursion_set, true);
93
94 if(depth < object_factory_params.min_null_tree_depth)
95 {
96 // Add the following code to assignments:
97 // <expr> = <aoe>;
98 assignments.append(non_null_inst);
99 }
100 else
101 {
102 // Add the following code to assignments:
103 // IF !NONDET(_Bool) THEN GOTO <label1>
104 // <expr> = <null pointer>
105 // GOTO <label2>
106 // <label1>: <expr> = &tmp$<temporary_counter>;
107 // <code from recursive call to gen_nondet_init() with
108 // tmp$<temporary_counter>>
109 // And the next line is labelled label2
112
115 std::move(set_null_inst),
116 std::move(non_null_inst));
117
118 assignments.add(std::move(null_check));
119 }
120 }
121 else if(type.id() == ID_struct_tag)
122 {
123 const auto &struct_tag_type = to_struct_tag_type(type);
124
125 const irep_idt struct_tag = struct_tag_type.get_identifier();
126
127 recursion_set.insert(struct_tag);
128
130
131 for(const auto &component : struct_type.components())
132 {
133 const typet &component_type = component.type();
134
135 if(!assign_const && component_type.get_bool(ID_C_constant))
136 {
137 continue;
138 }
139
140 const irep_idt name = component.get_name();
141
142 member_exprt me(expr, name, component_type);
143 me.add_source_location() = loc;
144
145 gen_nondet_init(assignments, me, depth, recursion_set, assign_const);
146 }
147 }
148 else if(type.id() == ID_array)
149 {
150 gen_nondet_array_init(assignments, expr, depth, recursion_set);
151 }
152 else
153 {
154 // If type is a ID_c_bool then add the following code to assignments:
155 // <expr> = NONDET(_BOOL);
156 // Else add the following code to assignments:
157 // <expr> = NONDET(type);
158 exprt rhs = type.id() == ID_c_bool ? get_nondet_bool(type, loc)
160 code_frontend_assignt assign(expr, rhs);
161 assign.add_source_location()=loc;
162
163 assignments.add(std::move(assign));
164 }
165}
166
168 code_blockt &assignments,
169 const exprt &expr,
170 std::size_t depth,
171 const recursion_sett &recursion_set)
172{
173 auto const &array_type = to_array_type(expr.type());
174 const auto &size = array_type.size();
175 PRECONDITION(size.is_constant());
178 array_size.has_value() && *array_size >= 0,
179 "Arrays should have positive size");
180 for(mp_integer index = 0; index < *array_size; ++index)
181 {
183 assignments,
184 index_exprt(expr, from_integer(index, size_type())),
185 depth,
186 recursion_set);
187 }
188}
189
205 symbol_table_baset &symbol_table,
206 const irep_idt base_name,
207 const typet &type,
208 const source_locationt &loc,
209 const c_object_factory_parameterst &object_factory_parameters,
210 const lifetimet lifetime)
211{
212 const symbolt &main_symbol = get_fresh_aux_symbol(
213 type,
215 id2string(base_name),
216 loc,
217 ID_C,
218 symbol_table);
220
221 symbol_factoryt state(
222 symbol_table,
223 loc,
225 object_factory_parameters,
226 lifetime);
227
228 code_blockt assignments;
229 state.gen_nondet_init(assignments, main_symbol_expr);
230
231 state.add_created_symbol(main_symbol);
233
234 init_code.append(assignments);
235
237
238 return main_symbol_expr;
239}
lifetimet
Selects the kind of objects allocated.
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
symbol_exprt c_nondet_symbol_factory(code_blockt &init_code, symbol_table_baset &symbol_table, const irep_idt base_name, const typet &type, const source_locationt &loc, const c_object_factory_parameterst &object_factory_parameters, const lifetimet lifetime)
Creates a symbol and generates code so that it can vary over all possible values for its type.
C Nondet Symbol Factory.
pointer_typet pointer_type(const typet &subtype)
Definition c_types.cpp:235
bitvector_typet char_type()
Definition c_types.cpp:106
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
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,...
The Boolean type.
Definition std_types.h:36
A codet representing sequential composition of program statements.
Definition std_code.h:130
void append(const code_blockt &extra_block)
Add all the codets from extra_block to the current code_blockt.
Definition std_code.cpp:86
void add(const codet &code)
Definition std_code.h:168
A codet representing an assignment in the program.
Definition std_code.h:24
codet representation of an if-then-else statement.
Definition std_code.h:460
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
typet & type()
Return the type of the expression.
Definition expr.h:84
source_locationt & add_source_location()
Definition expr.h:236
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Array index operator.
Definition std_expr.h:1470
bool get_bool(const irep_idt &name) const
Definition irep.cpp:57
const irep_idt & id() const
Definition irep.h:388
Extract member of struct or union.
Definition std_expr.h:2971
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition namespace.cpp:49
The null pointer constant.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
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.
Definition std_code.h:1520
Expression to hold a symbol (variable)
Definition std_expr.h:131
void gen_nondet_array_init(code_blockt &assignments, const exprt &expr, std::size_t depth, const recursion_sett &recursion_set)
Generate initialisation code for each array element.
void gen_nondet_init(code_blockt &assignments, const exprt &expr, const std::size_t depth=0, recursion_sett recursion_set=recursion_sett(), const bool assign_const=true)
Creates a nondet for expr, including calling itself recursively to make appropriate symbols to point ...
allocate_objectst allocate_objects
void add_created_symbol(const symbolt &symbol)
std::set< irep_idt > recursion_sett
void mark_created_symbols_as_input(code_blockt &init_code)
const c_object_factory_parameterst & object_factory_params
void declare_created_symbols(code_blockt &init_code)
const source_locationt & loc
The symbol table base class interface.
Symbol table entry.
Definition symbol.h:28
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition symbol.cpp:121
The type of an expression, extends irept.
Definition type.h:29
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 ...
Fresh auxiliary symbol creation.
Goto Programs with Functions.
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
Nondeterministic boolean helper.
exprt get_nondet_bool(const typet &type, const source_locationt &source_location)
Definition nondet_bool.h:21
API to expression classes for Pointers.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define PRECONDITION(CONDITION)
Definition invariant.h:463
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition std_expr.cpp:97
API to expression classes.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition std_expr.h:3172
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:518
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888
Symbol table entry.
#define size_type
Definition unistd.c:186