Skip to content

Commit c8f15e2

Browse files
committed
Adapt c nondet symbol factory for use in function body generation
1 parent e605b57 commit c8f15e2

File tree

3 files changed

+97
-67
lines changed

3 files changed

+97
-67
lines changed

src/ansi-c/ansi_c_entry_point.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ exprt::operandst build_function_environment(
4242
base_name,
4343
p.type(),
4444
p.source_location(),
45-
object_factory_parameters);
45+
object_factory_parameters,
46+
lifetimet::AUTOMATIC_LOCAL);
4647
}
4748

4849
return main_arguments;

src/ansi-c/c_nondet_symbol_factory.cpp

Lines changed: 25 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,79 +25,29 @@ Author: Diffblue Ltd.
2525

2626
#include <goto-programs/goto_functions.h>
2727

28-
class symbol_factoryt
29-
{
30-
symbol_tablet &symbol_table;
31-
const source_locationt &loc;
32-
namespacet ns;
33-
const c_object_factory_parameterst &object_factory_params;
34-
35-
allocate_objectst allocate_objects;
36-
37-
typedef std::set<irep_idt> recursion_sett;
38-
39-
public:
40-
symbol_factoryt(
41-
symbol_tablet &_symbol_table,
42-
const source_locationt &loc,
43-
const c_object_factory_parameterst &object_factory_params)
44-
: symbol_table(_symbol_table),
45-
loc(loc),
46-
ns(_symbol_table),
47-
object_factory_params(object_factory_params),
48-
allocate_objects(ID_C, loc, loc.get_function(), symbol_table)
49-
{}
50-
51-
void gen_nondet_init(
52-
code_blockt &assignments,
53-
const exprt &expr,
54-
const std::size_t depth = 0,
55-
recursion_sett recursion_set = recursion_sett());
56-
57-
void add_created_symbol(const symbolt *symbol_ptr)
58-
{
59-
allocate_objects.add_created_symbol(symbol_ptr);
60-
}
61-
62-
void declare_created_symbols(code_blockt &init_code)
63-
{
64-
allocate_objects.declare_created_symbols(init_code);
65-
}
66-
67-
void mark_created_symbols_as_input(code_blockt &init_code)
68-
{
69-
allocate_objects.mark_created_symbols_as_input(init_code);
70-
}
71-
72-
private:
73-
/// Generate initialisation code for each array element
74-
/// \param assignments: The code block to add code to
75-
/// \param expr: An expression of array type
76-
/// \param depth: The struct recursion depth
77-
/// \param recursion_set: The struct recursion set
78-
/// \see gen_nondet_init For the meaning of the last 2 parameters
79-
void gen_nondet_array_init(
80-
code_blockt &assignments,
81-
const exprt &expr,
82-
std::size_t depth,
83-
const recursion_sett &recursion_set);
84-
};
85-
8628
/// Creates a nondet for expr, including calling itself recursively to make
8729
/// appropriate symbols to point to if expr is a pointer.
8830
/// \param assignments: The code block to add code to
8931
/// \param expr: The expression which we are generating a non-determinate value
9032
/// for
9133
/// \param depth number of pointers followed so far during initialisation
9234
/// \param recursion_set names of structs seen so far on current pointer chain
35+
/// \param assign_const Indicates whether const objects should be nondet
36+
/// initialized
9337
void symbol_factoryt::gen_nondet_init(
9438
code_blockt &assignments,
9539
const exprt &expr,
9640
const std::size_t depth,
97-
recursion_sett recursion_set)
41+
recursion_sett recursion_set,
42+
const bool assign_const)
9843
{
9944
const typet &type=ns.follow(expr.type());
10045

46+
if(!assign_const && expr.type().get_bool(ID_C_constant))
47+
{
48+
return;
49+
}
50+
10151
if(type.id()==ID_pointer)
10252
{
10353
// dereferenced type
@@ -121,10 +71,10 @@ void symbol_factoryt::gen_nondet_init(
12171

12272
code_blockt non_null_inst;
12373

124-
exprt init_expr = allocate_objects.allocate_automatic_local_object(
125-
non_null_inst, expr, subtype);
74+
exprt init_expr =
75+
allocate_objects.allocate_object(non_null_inst, expr, subtype, lifetime);
12676

127-
gen_nondet_init(non_null_inst, init_expr, depth + 1, recursion_set);
77+
gen_nondet_init(non_null_inst, init_expr, depth + 1, recursion_set, true);
12878

12979
if(depth < object_factory_params.min_null_tree_depth)
13080
{
@@ -164,12 +114,18 @@ void symbol_factoryt::gen_nondet_init(
164114
for(const auto &component : struct_type.components())
165115
{
166116
const typet &component_type = component.type();
117+
118+
if(!assign_const && component_type.get_bool(ID_C_constant))
119+
{
120+
continue;
121+
}
122+
167123
const irep_idt name = component.get_name();
168124

169125
member_exprt me(expr, name, component_type);
170126
me.add_source_location() = loc;
171127

172-
gen_nondet_init(assignments, me, depth, recursion_set);
128+
gen_nondet_init(assignments, me, depth, recursion_set, assign_const);
173129
}
174130
}
175131
else if(type.id() == ID_array)
@@ -220,14 +176,17 @@ void symbol_factoryt::gen_nondet_array_init(
220176
/// \param loc: The location to assign to generated code
221177
/// \param object_factory_parameters configuration parameters for the object
222178
/// factory
179+
/// \param lifetime: Lifetime of the allocated object (AUTOMATIC_LOCAL,
180+
/// STATIC_GLOBAL, or DYNAMIC)
223181
/// \return Returns the symbol_exprt for the symbol created
224182
symbol_exprt c_nondet_symbol_factory(
225183
code_blockt &init_code,
226184
symbol_tablet &symbol_table,
227185
const irep_idt base_name,
228186
const typet &type,
229187
const source_locationt &loc,
230-
const c_object_factory_parameterst &object_factory_parameters)
188+
const c_object_factory_parameterst &object_factory_parameters,
189+
const lifetimet lifetime)
231190
{
232191
irep_idt identifier=id2string(goto_functionst::entry_point())+
233192
"::"+id2string(base_name);
@@ -246,7 +205,8 @@ symbol_exprt c_nondet_symbol_factory(
246205
bool moving_symbol_failed=symbol_table.move(main_symbol, main_symbol_ptr);
247206
CHECK_RETURN(!moving_symbol_failed);
248207

249-
symbol_factoryt state(symbol_table, loc, object_factory_parameters);
208+
symbol_factoryt state(symbol_table, loc, object_factory_parameters, lifetime);
209+
250210
code_blockt assignments;
251211
state.gen_nondet_init(assignments, main_symbol_expr);
252212

src/ansi-c/c_nondet_symbol_factory.h

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,84 @@ Author: Diffblue Ltd.
1414

1515
#include "c_object_factory_parameters.h"
1616

17+
#include <set>
18+
#include <vector>
19+
20+
#include <util/allocate_objects.h>
1721
#include <util/std_code.h>
1822
#include <util/symbol_table.h>
1923

24+
class symbol_factoryt
25+
{
26+
symbol_tablet &symbol_table;
27+
const source_locationt &loc;
28+
namespacet ns;
29+
const c_object_factory_parameterst &object_factory_params;
30+
31+
allocate_objectst allocate_objects;
32+
33+
const lifetimet lifetime;
34+
35+
public:
36+
typedef std::set<irep_idt> recursion_sett;
37+
38+
symbol_factoryt(
39+
symbol_tablet &_symbol_table,
40+
const source_locationt &loc,
41+
const c_object_factory_parameterst &object_factory_params,
42+
const lifetimet lifetime)
43+
: symbol_table(_symbol_table),
44+
loc(loc),
45+
ns(_symbol_table),
46+
object_factory_params(object_factory_params),
47+
allocate_objects(ID_C, loc, loc.get_function(), symbol_table),
48+
lifetime(lifetime)
49+
{
50+
}
51+
52+
void gen_nondet_init(
53+
code_blockt &assignments,
54+
const exprt &expr,
55+
const std::size_t depth = 0,
56+
recursion_sett recursion_set = recursion_sett(),
57+
const bool assign_const = true);
58+
59+
void add_created_symbol(const symbolt *symbol_ptr)
60+
{
61+
allocate_objects.add_created_symbol(symbol_ptr);
62+
}
63+
64+
void declare_created_symbols(code_blockt &init_code)
65+
{
66+
allocate_objects.declare_created_symbols(init_code);
67+
}
68+
69+
void mark_created_symbols_as_input(code_blockt &init_code)
70+
{
71+
allocate_objects.mark_created_symbols_as_input(init_code);
72+
}
73+
74+
private:
75+
/// Generate initialisation code for each array element
76+
/// \param assignments: The code block to add code to
77+
/// \param expr: An expression of array type
78+
/// \param depth: The struct recursion depth
79+
/// \param recursion_set: The struct recursion set
80+
/// \see gen_nondet_init For the meaning of the last 2 parameters
81+
void gen_nondet_array_init(
82+
code_blockt &assignments,
83+
const exprt &expr,
84+
std::size_t depth,
85+
const recursion_sett &recursion_set);
86+
};
87+
2088
symbol_exprt c_nondet_symbol_factory(
2189
code_blockt &init_code,
2290
symbol_tablet &symbol_table,
2391
const irep_idt base_name,
2492
const typet &type,
2593
const source_locationt &,
26-
const c_object_factory_parameterst &object_factory_parameters);
94+
const c_object_factory_parameterst &object_factory_parameters,
95+
const lifetimet lifetime);
2796

2897
#endif // CPROVER_ANSI_C_C_NONDET_SYMBOL_FACTORY_H

0 commit comments

Comments
 (0)