Skip to content

Commit 60395ea

Browse files
committed
Add recursive nondet struct initialization
1 parent 29f9419 commit 60395ea

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/ansi-c/ansi_c_entry_point.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ exprt::operandst build_function_environment(
4242
base_name,
4343
p.type(),
4444
p.source_location(),
45-
true,
4645
object_factory_parameters);
4746
}
4847

src/ansi-c/c_nondet_symbol_factory.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Author: Diffblue Ltd.
1111

1212
#include "c_nondet_symbol_factory.h"
1313

14+
#include <ansi-c/c_object_factory_parameters.h>
15+
1416
#include <util/arith_tools.h>
1517
#include <util/c_types.h>
1618
#include <util/fresh_symbol.h>
@@ -31,6 +33,8 @@ class symbol_factoryt
3133
namespacet ns;
3234
const c_object_factory_parameterst &object_factory_params;
3335

36+
typedef std::set<irep_idt> recursion_sett;
37+
3438
const symbolt &c_new_tmp_symbol(
3539
//symbol_tablet &symbol_table,
3640
//const source_locationt &loc,
@@ -59,7 +63,11 @@ class symbol_factoryt
5963
const typet &allocate_type,
6064
const bool static_lifetime);
6165

62-
void gen_nondet_init(code_blockt &assignments, const exprt &expr);
66+
void gen_nondet_init(
67+
code_blockt &assignments,
68+
const exprt &expr,
69+
const std::size_t depth = 0,
70+
recursion_sett recursion_set = recursion_sett());
6371
};
6472

6573
/// Create a new temporary static symbol
@@ -129,7 +137,9 @@ exprt symbol_factoryt::allocate_object(
129137
/// for
130138
void symbol_factoryt::gen_nondet_init(
131139
code_blockt &assignments,
132-
const exprt &expr)
140+
const exprt &expr,
141+
const std::size_t depth,
142+
recursion_sett recursion_set)
133143
{
134144
const typet &type=ns.follow(expr.type());
135145

@@ -139,6 +149,22 @@ void symbol_factoryt::gen_nondet_init(
139149
const pointer_typet &pointer_type=to_pointer_type(type);
140150
const typet &subtype=ns.follow(pointer_type.subtype());
141151

152+
if(subtype.id() == ID_struct)
153+
{
154+
const struct_typet &struct_type = to_struct_type(subtype);
155+
const irep_idt struct_tag = struct_type.get_tag();
156+
157+
if(
158+
recursion_set.find(struct_tag) != recursion_set.end() &&
159+
depth >= object_factory_params.max_nondet_tree_depth)
160+
{
161+
code_assignt c(expr, null_pointer_exprt(pointer_type));
162+
assignments.move(c);
163+
164+
return;
165+
}
166+
}
167+
142168
code_blockt non_null_inst;
143169

144170
exprt allocated=allocate_object(non_null_inst, expr, subtype, false);
@@ -152,7 +178,7 @@ void symbol_factoryt::gen_nondet_init(
152178
{
153179
init_expr=dereference_exprt(allocated, allocated.type().subtype());
154180
}
155-
gen_nondet_init(non_null_inst, init_expr);
181+
gen_nondet_init(non_null_inst, init_expr, depth + 1, recursion_set);
156182

157183
if(assume_non_null)
158184
{
@@ -181,7 +207,25 @@ void symbol_factoryt::gen_nondet_init(
181207
assignments.move(null_check);
182208
}
183209
}
184-
// TODO(OJones): Add support for structs and arrays
210+
else if(type.id() == ID_struct)
211+
{
212+
const struct_typet &struct_type = to_struct_type(type);
213+
214+
const irep_idt struct_tag = struct_type.get_tag();
215+
216+
recursion_set.insert(struct_tag);
217+
218+
for(const auto &component : struct_type.components())
219+
{
220+
const typet &component_type = component.type();
221+
const irep_idt name = component.get_name();
222+
223+
member_exprt me(expr, name, component_type);
224+
me.add_source_location() = loc;
225+
226+
gen_nondet_init(assignments, me, depth, recursion_set);
227+
}
228+
}
185229
else
186230
{
187231
// If type is a ID_c_bool then add the following code to assignments:
@@ -213,7 +257,6 @@ exprt c_nondet_symbol_factory(
213257
const irep_idt base_name,
214258
const typet &type,
215259
const source_locationt &loc,
216-
bool allow_null,
217260
const c_object_factory_parameterst &object_factory_parameters)
218261
{
219262
irep_idt identifier=id2string(goto_functionst::entry_point())+
@@ -236,6 +279,8 @@ exprt c_nondet_symbol_factory(
236279
std::vector<const symbolt *> symbols_created;
237280
symbols_created.push_back(main_symbol_ptr);
238281

282+
const bool allow_null = (object_factory_parameters.min_null_tree_depth == 0);
283+
239284
symbol_factoryt state(
240285
symbols_created, symbol_table, loc, !allow_null, object_factory_parameters);
241286
code_blockt assignments;

src/ansi-c/c_nondet_symbol_factory.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ exprt c_nondet_symbol_factory(
2323
const irep_idt base_name,
2424
const typet &type,
2525
const source_locationt &,
26-
bool allow_null,
2726
const c_object_factory_parameterst &object_factory_parameters);
2827

2928
#endif // CPROVER_ANSI_C_C_NONDET_SYMBOL_FACTORY_H

0 commit comments

Comments
 (0)