@@ -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
public:
35
39
symbol_factoryt (
36
40
std::vector<const symbolt *> &_symbols_created,
@@ -52,7 +56,11 @@ class symbol_factoryt
52
56
const typet &allocate_type,
53
57
const bool static_lifetime);
54
58
55
- void gen_nondet_init (code_blockt &assignments, const exprt &expr);
59
+ void gen_nondet_init (
60
+ code_blockt &assignments,
61
+ const exprt &expr,
62
+ const std::size_t depth = 0 ,
63
+ recursion_sett recursion_set = recursion_sett());
56
64
};
57
65
58
66
// / Create a symbol for a pointer to point to
@@ -103,9 +111,13 @@ exprt symbol_factoryt::allocate_object(
103
111
// / \param assignments: The code block to add code to
104
112
// / \param expr: The expression which we are generating a non-determinate value
105
113
// / for
114
+ // / \param depth number of pointers followed so far during initialisation
115
+ // / \param recursion_set names of structs seen so far on current pointer chain
106
116
void symbol_factoryt::gen_nondet_init (
107
117
code_blockt &assignments,
108
- const exprt &expr)
118
+ const exprt &expr,
119
+ const std::size_t depth,
120
+ recursion_sett recursion_set)
109
121
{
110
122
const typet &type=ns.follow (expr.type ());
111
123
@@ -115,6 +127,22 @@ void symbol_factoryt::gen_nondet_init(
115
127
const pointer_typet &pointer_type=to_pointer_type (type);
116
128
const typet &subtype=ns.follow (pointer_type.subtype ());
117
129
130
+ if (subtype.id () == ID_struct)
131
+ {
132
+ const struct_typet &struct_type = to_struct_type (subtype);
133
+ const irep_idt struct_tag = struct_type.get_tag ();
134
+
135
+ if (
136
+ recursion_set.find (struct_tag) != recursion_set.end () &&
137
+ depth >= object_factory_params.max_nondet_tree_depth )
138
+ {
139
+ code_assignt c (expr, null_pointer_exprt (pointer_type));
140
+ assignments.move (c);
141
+
142
+ return ;
143
+ }
144
+ }
145
+
118
146
code_blockt non_null_inst;
119
147
120
148
exprt allocated=allocate_object (non_null_inst, expr, subtype, false );
@@ -128,7 +156,7 @@ void symbol_factoryt::gen_nondet_init(
128
156
{
129
157
init_expr=dereference_exprt (allocated, allocated.type ().subtype ());
130
158
}
131
- gen_nondet_init (non_null_inst, init_expr);
159
+ gen_nondet_init (non_null_inst, init_expr, depth + 1 , recursion_set );
132
160
133
161
if (assume_non_null)
134
162
{
@@ -157,7 +185,25 @@ void symbol_factoryt::gen_nondet_init(
157
185
assignments.move (null_check);
158
186
}
159
187
}
160
- // TODO(OJones): Add support for structs and arrays
188
+ else if (type.id () == ID_struct)
189
+ {
190
+ const struct_typet &struct_type = to_struct_type (type);
191
+
192
+ const irep_idt struct_tag = struct_type.get_tag ();
193
+
194
+ recursion_set.insert (struct_tag);
195
+
196
+ for (const auto &component : struct_type.components ())
197
+ {
198
+ const typet &component_type = component.type ();
199
+ const irep_idt name = component.get_name ();
200
+
201
+ member_exprt me (expr, name, component_type);
202
+ me.add_source_location () = loc;
203
+
204
+ gen_nondet_init (assignments, me, depth, recursion_set);
205
+ }
206
+ }
161
207
else
162
208
{
163
209
// If type is a ID_c_bool then add the following code to assignments:
@@ -189,7 +235,6 @@ exprt c_nondet_symbol_factory(
189
235
const irep_idt base_name,
190
236
const typet &type,
191
237
const source_locationt &loc,
192
- bool allow_null,
193
238
const c_object_factory_parameterst &object_factory_parameters)
194
239
{
195
240
irep_idt identifier=id2string (goto_functionst::entry_point ())+
@@ -212,6 +257,8 @@ exprt c_nondet_symbol_factory(
212
257
std::vector<const symbolt *> symbols_created;
213
258
symbols_created.push_back (main_symbol_ptr);
214
259
260
+ const bool allow_null = (object_factory_parameters.min_null_tree_depth == 0 );
261
+
215
262
symbol_factoryt state (
216
263
symbols_created, symbol_table, loc, !allow_null, object_factory_parameters);
217
264
code_blockt assignments;
0 commit comments