@@ -69,7 +69,7 @@ class assume_false_generate_function_bodiest : public generate_function_bodiest
69
69
protected:
70
70
void generate_function_body_impl (
71
71
goto_functiont &function,
72
- const symbol_tablet &symbol_table,
72
+ symbol_tablet &symbol_table,
73
73
const irep_idt &function_name) const override
74
74
{
75
75
auto const &function_symbol = symbol_table.lookup_ref (function_name);
@@ -92,7 +92,7 @@ class assert_false_generate_function_bodiest : public generate_function_bodiest
92
92
protected:
93
93
void generate_function_body_impl (
94
94
goto_functiont &function,
95
- const symbol_tablet &symbol_table,
95
+ symbol_tablet &symbol_table,
96
96
const irep_idt &function_name) const override
97
97
{
98
98
auto const &function_symbol = symbol_table.lookup_ref (function_name);
@@ -123,7 +123,7 @@ class assert_false_then_assume_false_generate_function_bodiest
123
123
protected:
124
124
void generate_function_body_impl (
125
125
goto_functiont &function,
126
- const symbol_tablet &symbol_table,
126
+ symbol_tablet &symbol_table,
127
127
const irep_idt &function_name) const override
128
128
{
129
129
auto const &function_symbol = symbol_table.lookup_ref (function_name);
@@ -171,97 +171,42 @@ class havoc_generate_function_bodiest : public generate_function_bodiest,
171
171
private:
172
172
void havoc_expr_rec (
173
173
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
177
178
{
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))
182
- {
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
- }
258
- }
179
+ symbol_factoryt symbol_factory (
180
+ symbol_table,
181
+ source_location,
182
+ object_factory_parameters,
183
+ lifetimet::DYNAMIC);
184
+
185
+ code_blockt assignments;
186
+
187
+ symbol_factory.gen_nondet_init (
188
+ assignments,
189
+ lhs,
190
+ initial_depth, // depth 1 since we pass the dereferenced pointer
191
+ symbol_factoryt::recursion_sett (),
192
+ false ); // do not initialize const objects at the top level
193
+
194
+ code_blockt init_code;
195
+
196
+ symbol_factory.declare_created_symbols (init_code);
197
+ init_code.append (assignments);
198
+
199
+ null_message_handlert nmh;
200
+ goto_programt tmp_dest;
201
+ goto_convert (init_code, symbol_table, tmp_dest, nmh, ID_C);
202
+
203
+ dest.destructive_append (tmp_dest);
259
204
}
260
205
261
206
protected:
262
207
void generate_function_body_impl (
263
208
goto_functiont &function,
264
- const symbol_tablet &symbol_table,
209
+ symbol_tablet &symbol_table,
265
210
const irep_idt &function_name) const override
266
211
{
267
212
auto const &function_symbol = symbol_table.lookup_ref (function_name);
@@ -277,18 +222,25 @@ class havoc_generate_function_bodiest : public generate_function_bodiest,
277
222
{
278
223
if (
279
224
parameter.type ().id () == ID_pointer &&
225
+ !parameter.type ().subtype ().get_bool (ID_C_constant) &&
280
226
std::regex_match (
281
227
id2string (parameter.get_base_name ()), parameters_to_havoc))
282
228
{
283
- // if (param != nullptr) { *param = nondet(); }
284
229
auto goto_instruction = add_instruction ();
230
+
231
+ const irep_idt base_name = parameter.get_base_name ();
232
+ CHECK_RETURN (!base_name.empty ());
233
+
234
+ dereference_exprt dereference_expr (
235
+ symbol_exprt (parameter.get_identifier (), parameter.type ()),
236
+ parameter.type ().subtype ());
237
+
238
+ goto_programt dest;
285
239
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);
240
+ dereference_expr, 1 , function_symbol.location , symbol_table, dest);
241
+
242
+ function.body .destructive_append (dest);
243
+
292
244
auto label_instruction = add_instruction ();
293
245
goto_instruction->make_goto (
294
246
label_instruction,
@@ -302,19 +254,25 @@ class havoc_generate_function_bodiest : public generate_function_bodiest,
302
254
for (auto const &global_id : globals_to_havoc)
303
255
{
304
256
auto const &global_sym = symbol_table.lookup_ref (global_id);
257
+
258
+ goto_programt dest;
259
+
305
260
havoc_expr_rec (
306
261
symbol_exprt (global_sym.name , global_sym.type ),
307
- ns,
308
- add_instruction,
309
- function_name);
262
+ 0 ,
263
+ function_symbol.location ,
264
+ symbol_table,
265
+ dest);
266
+
267
+ function.body .destructive_append (dest);
310
268
}
269
+
311
270
if (function.type .return_type () != void_typet ())
312
271
{
313
272
auto return_instruction = add_instruction ();
314
273
return_instruction->make_return ();
315
- return_instruction->code = code_returnt (
316
- side_effect_expr_nondett (
317
- function.type .return_type (), function_symbol.location ));
274
+ return_instruction->code = code_returnt (side_effect_expr_nondett (
275
+ function.type .return_type (), function_symbol.location ));
318
276
}
319
277
auto end_function_instruction = add_instruction ();
320
278
end_function_instruction->make_end_function ();
0 commit comments