Skip to content

Commit 71185a1

Browse files
committed
Use c nondet object factory in function body generation
1 parent 3b5ddb5 commit 71185a1

File tree

2 files changed

+66
-97
lines changed

2 files changed

+66
-97
lines changed

src/goto-programs/generate_function_bodies.cpp

Lines changed: 65 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class assume_false_generate_function_bodiest : public generate_function_bodiest
6969
protected:
7070
void generate_function_body_impl(
7171
goto_functiont &function,
72-
const symbol_tablet &symbol_table,
72+
symbol_tablet &symbol_table,
7373
const irep_idt &function_name) const override
7474
{
7575
auto const &function_symbol = symbol_table.lookup_ref(function_name);
@@ -92,7 +92,7 @@ class assert_false_generate_function_bodiest : public generate_function_bodiest
9292
protected:
9393
void generate_function_body_impl(
9494
goto_functiont &function,
95-
const symbol_tablet &symbol_table,
95+
symbol_tablet &symbol_table,
9696
const irep_idt &function_name) const override
9797
{
9898
auto const &function_symbol = symbol_table.lookup_ref(function_name);
@@ -123,7 +123,7 @@ class assert_false_then_assume_false_generate_function_bodiest
123123
protected:
124124
void generate_function_body_impl(
125125
goto_functiont &function,
126-
const symbol_tablet &symbol_table,
126+
symbol_tablet &symbol_table,
127127
const irep_idt &function_name) const override
128128
{
129129
auto const &function_symbol = symbol_table.lookup_ref(function_name);
@@ -171,97 +171,52 @@ class havoc_generate_function_bodiest : public generate_function_bodiest,
171171
private:
172172
void havoc_expr_rec(
173173
const exprt &lhs,
174-
const namespacet &ns,
175-
const std::function<goto_programt::targett(void)> &add_instruction,
176-
const irep_idt &function_name) const
174+
const std::size_t initial_depth,
175+
const source_locationt &source_location,
176+
symbol_tablet &symbol_table,
177+
goto_programt &dest) const
177178
{
178-
// resolve type symbols
179-
auto const lhs_type = ns.follow(lhs.type());
180-
// skip constants
181-
if(!lhs_type.get_bool(ID_C_constant))
179+
std::vector<const symbolt *> symbols_created;
180+
181+
symbol_factoryt symbol_factory(
182+
symbols_created,
183+
symbol_table,
184+
source_location,
185+
object_factory_parameters,
186+
allocation_typet::DYNAMIC);
187+
188+
code_blockt assignments;
189+
190+
symbol_factory.gen_nondet_init(
191+
assignments,
192+
lhs,
193+
initial_depth, // depth 1 since we pass the dereferenced pointer
194+
symbol_factoryt::recursion_sett(),
195+
false); // do not initialize const objects at the top level
196+
197+
code_blockt init_code;
198+
199+
// declare added symbols
200+
for(const symbolt *const symbol_ptr : symbols_created)
182201
{
183-
// expand arrays, structs and union, everything else gets
184-
// assigned nondet
185-
if(lhs_type.id() == ID_struct || lhs_type.id() == ID_union)
186-
{
187-
// Note: In the case of unions it's often enough to assign
188-
// just one member; However consider a case like
189-
// union { struct { const int x; int y; } a;
190-
// struct { int x; const int y; } b;};
191-
// in this case both a.y and b.x must be assigned
192-
// otherwise these parts stay constant even though
193-
// they could've changed (note that type punning through
194-
// unions is allowed in the C standard but forbidden in C++)
195-
// so we're assigning all members even in the case of
196-
// unions just to be safe
197-
auto const lhs_struct_type = to_struct_union_type(lhs_type);
198-
for(auto const &component : lhs_struct_type.components())
199-
{
200-
havoc_expr_rec(
201-
member_exprt(lhs, component.get_name(), component.type()),
202-
ns,
203-
add_instruction,
204-
function_name);
205-
}
206-
}
207-
else if(lhs_type.id() == ID_array)
208-
{
209-
auto const lhs_array_type = to_array_type(lhs_type);
210-
if(!lhs_array_type.subtype().get_bool(ID_C_constant))
211-
{
212-
bool constant_known_array_size = lhs_array_type.size().is_constant();
213-
if(!constant_known_array_size)
214-
{
215-
warning() << "Cannot havoc non-const array " << format(lhs)
216-
<< " in function " << function_name
217-
<< ": Unknown array size" << eom;
218-
}
219-
else
220-
{
221-
auto const array_size =
222-
numeric_cast<mp_integer>(lhs_array_type.size());
223-
INVARIANT(
224-
array_size.has_value(),
225-
"Array size should be known constant integer");
226-
if(array_size.value() == 0)
227-
{
228-
// Pretty much the same thing as a unknown size array
229-
// Technically not allowed by the C standard, but we model
230-
// unknown size arrays in structs this way
231-
warning() << "Cannot havoc non-const array " << format(lhs)
232-
<< " in function " << function_name << ": Array size 0"
233-
<< eom;
234-
}
235-
else
236-
{
237-
for(mp_integer i = 0; i < array_size.value(); ++i)
238-
{
239-
auto const index =
240-
from_integer(i, lhs_array_type.size().type());
241-
havoc_expr_rec(
242-
index_exprt(lhs, index, lhs_array_type.subtype()),
243-
ns,
244-
add_instruction,
245-
function_name);
246-
}
247-
}
248-
}
249-
}
250-
}
251-
else
252-
{
253-
auto assign_instruction = add_instruction();
254-
assign_instruction->make_assignment(
255-
code_assignt(
256-
lhs, side_effect_expr_nondett(lhs_type, lhs.source_location())));
257-
}
202+
code_declt decl(symbol_ptr->symbol_expr());
203+
decl.add_source_location() = source_locationt();
204+
init_code.add(std::move(decl));
258205
}
206+
207+
init_code.append(assignments);
208+
209+
null_message_handlert nmh;
210+
goto_programt tmp_dest;
211+
goto_convert(init_code, symbol_table, tmp_dest, nmh, ID_C);
212+
213+
dest.destructive_append(tmp_dest);
259214
}
260215

261216
protected:
262217
void generate_function_body_impl(
263218
goto_functiont &function,
264-
const symbol_tablet &symbol_table,
219+
symbol_tablet &symbol_table,
265220
const irep_idt &function_name) const override
266221
{
267222
auto const &function_symbol = symbol_table.lookup_ref(function_name);
@@ -277,18 +232,25 @@ class havoc_generate_function_bodiest : public generate_function_bodiest,
277232
{
278233
if(
279234
parameter.type().id() == ID_pointer &&
235+
!parameter.type().subtype().get_bool(ID_C_constant) &&
280236
std::regex_match(
281237
id2string(parameter.get_base_name()), parameters_to_havoc))
282238
{
283-
// if (param != nullptr) { *param = nondet(); }
284239
auto goto_instruction = add_instruction();
240+
241+
const irep_idt base_name = parameter.get_base_name();
242+
CHECK_RETURN(!base_name.empty());
243+
244+
dereference_exprt dereference_expr(
245+
symbol_exprt(parameter.get_identifier(), parameter.type()),
246+
parameter.type().subtype());
247+
248+
goto_programt dest;
285249
havoc_expr_rec(
286-
dereference_exprt(
287-
symbol_exprt(parameter.get_identifier(), parameter.type()),
288-
parameter.type().subtype()),
289-
ns,
290-
add_instruction,
291-
function_name);
250+
dereference_expr, 1, function_symbol.location, symbol_table, dest);
251+
252+
function.body.destructive_append(dest);
253+
292254
auto label_instruction = add_instruction();
293255
goto_instruction->make_goto(
294256
label_instruction,
@@ -302,12 +264,19 @@ class havoc_generate_function_bodiest : public generate_function_bodiest,
302264
for(auto const &global_id : globals_to_havoc)
303265
{
304266
auto const &global_sym = symbol_table.lookup_ref(global_id);
267+
268+
goto_programt dest;
269+
305270
havoc_expr_rec(
306271
symbol_exprt(global_sym.name, global_sym.type),
307-
ns,
308-
add_instruction,
309-
function_name);
272+
0,
273+
function_symbol.location,
274+
symbol_table,
275+
dest);
276+
277+
function.body.destructive_append(dest);
310278
}
279+
311280
if(function.type.return_type() != void_typet())
312281
{
313282
auto return_instruction = add_instruction();

src/goto-programs/generate_function_bodies.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class generate_function_bodiest
3232
/// \param function_name Identifier of function
3333
virtual void generate_function_body_impl(
3434
goto_functiont &function,
35-
const symbol_tablet &symbol_table,
35+
symbol_tablet &symbol_table,
3636
const irep_idt &function_name) const = 0;
3737

3838
public:

0 commit comments

Comments
 (0)