@@ -11,6 +11,8 @@ Author: Diffblue Ltd.
11
11
12
12
#include " c_nondet_symbol_factory.h"
13
13
14
+ #include < ansi-c/c_object_factory_parameters.h>
15
+
14
16
#include < util/arith_tools.h>
15
17
#include < util/c_types.h>
16
18
#include < util/fresh_symbol.h>
@@ -31,6 +33,8 @@ class symbol_factoryt
31
33
namespacet ns;
32
34
const c_object_factory_parameterst &object_factory_params;
33
35
36
+ typedef std::set<irep_idt> recursion_sett;
37
+
34
38
const symbolt &c_new_tmp_symbol (
35
39
const typet &type,
36
40
const bool static_lifetime,
@@ -57,7 +61,11 @@ class symbol_factoryt
57
61
const typet &allocate_type,
58
62
const bool static_lifetime);
59
63
60
- void gen_nondet_init (code_blockt &assignments, const exprt &expr);
64
+ void gen_nondet_init (
65
+ code_blockt &assignments,
66
+ const exprt &expr,
67
+ const std::size_t depth = 0 ,
68
+ recursion_sett recursion_set = recursion_sett());
61
69
};
62
70
63
71
// / Create a new temporary static symbol
@@ -121,9 +129,13 @@ exprt symbol_factoryt::allocate_object(
121
129
// / \param assignments: The code block to add code to
122
130
// / \param expr: The expression which we are generating a non-determinate value
123
131
// / for
132
+ // / \param depth number of pointers followed so far during initialisation
133
+ // / \param recursion_set names of structs seen so far on current pointer chain
124
134
void symbol_factoryt::gen_nondet_init (
125
135
code_blockt &assignments,
126
- const exprt &expr)
136
+ const exprt &expr,
137
+ const std::size_t depth,
138
+ recursion_sett recursion_set)
127
139
{
128
140
const typet &type=ns.follow (expr.type ());
129
141
@@ -133,6 +145,22 @@ void symbol_factoryt::gen_nondet_init(
133
145
const pointer_typet &pointer_type=to_pointer_type (type);
134
146
const typet &subtype=ns.follow (pointer_type.subtype ());
135
147
148
+ if (subtype.id () == ID_struct)
149
+ {
150
+ const struct_typet &struct_type = to_struct_type (subtype);
151
+ const irep_idt struct_tag = struct_type.get_tag ();
152
+
153
+ if (
154
+ recursion_set.find (struct_tag) != recursion_set.end () &&
155
+ depth >= object_factory_params.max_nondet_tree_depth )
156
+ {
157
+ code_assignt c (expr, null_pointer_exprt (pointer_type));
158
+ assignments.move (c);
159
+
160
+ return ;
161
+ }
162
+ }
163
+
136
164
code_blockt non_null_inst;
137
165
138
166
exprt allocated=allocate_object (non_null_inst, expr, subtype, false );
@@ -146,7 +174,7 @@ void symbol_factoryt::gen_nondet_init(
146
174
{
147
175
init_expr=dereference_exprt (allocated, allocated.type ().subtype ());
148
176
}
149
- gen_nondet_init (non_null_inst, init_expr);
177
+ gen_nondet_init (non_null_inst, init_expr, depth + 1 , recursion_set );
150
178
151
179
if (assume_non_null)
152
180
{
@@ -175,7 +203,25 @@ void symbol_factoryt::gen_nondet_init(
175
203
assignments.move (null_check);
176
204
}
177
205
}
178
- // TODO(OJones): Add support for structs and arrays
206
+ else if (type.id () == ID_struct)
207
+ {
208
+ const struct_typet &struct_type = to_struct_type (type);
209
+
210
+ const irep_idt struct_tag = struct_type.get_tag ();
211
+
212
+ recursion_set.insert (struct_tag);
213
+
214
+ for (const auto &component : struct_type.components ())
215
+ {
216
+ const typet &component_type = component.type ();
217
+ const irep_idt name = component.get_name ();
218
+
219
+ member_exprt me (expr, name, component_type);
220
+ me.add_source_location () = loc;
221
+
222
+ gen_nondet_init (assignments, me, depth, recursion_set);
223
+ }
224
+ }
179
225
else
180
226
{
181
227
// If type is a ID_c_bool then add the following code to assignments:
@@ -207,7 +253,6 @@ exprt c_nondet_symbol_factory(
207
253
const irep_idt base_name,
208
254
const typet &type,
209
255
const source_locationt &loc,
210
- bool allow_null,
211
256
const c_object_factory_parameterst &object_factory_parameters)
212
257
{
213
258
irep_idt identifier=id2string (goto_functionst::entry_point ())+
@@ -230,6 +275,8 @@ exprt c_nondet_symbol_factory(
230
275
std::vector<const symbolt *> symbols_created;
231
276
symbols_created.push_back (main_symbol_ptr);
232
277
278
+ const bool allow_null = (object_factory_parameters.min_null_tree_depth == 0 );
279
+
233
280
symbol_factoryt state (
234
281
symbols_created, symbol_table, loc, !allow_null, object_factory_parameters);
235
282
code_blockt assignments;
0 commit comments