@@ -103,6 +103,7 @@ void dfcc_spec_functionst::generate_havoc_function(
103
103
havoc_function_id,
104
104
original_program,
105
105
write_set_symbol.symbol_expr (),
106
+ dfcc_ptr_havoc_modet::INVALID,
106
107
havoc_program,
107
108
nof_targets);
108
109
@@ -144,6 +145,7 @@ void dfcc_spec_functionst::generate_havoc_instructions(
144
145
const irep_idt &function_id,
145
146
const goto_programt &original_program,
146
147
const exprt &write_set_to_havoc,
148
+ dfcc_ptr_havoc_modet ptr_havoc_mode,
147
149
goto_programt &havoc_program,
148
150
std::size_t &nof_targets)
149
151
{
@@ -191,8 +193,9 @@ void dfcc_spec_functionst::generate_havoc_instructions(
191
193
// DECL __havoc_target;
192
194
// CALL __havoc_target = havoc_hook(set, next_idx);
193
195
// IF !__havoc_target GOTO label;
194
- // ASSIGN *__havoc_target = nondet(target_type);
195
- // label: DEAD __havoc_target;
196
+ // .... add code for scalar or pointer targets ...
197
+ // label:
198
+ // DEAD __havoc_target;
196
199
// ```
197
200
// declare a local var to store targets havoced via nondet assignment
198
201
auto &target_type = get_target_type (ins_it->call_arguments ().at (0 ));
@@ -213,13 +216,42 @@ void dfcc_spec_functionst::generate_havoc_instructions(
213
216
havoc_program.add (goto_programt::make_incomplete_goto (
214
217
dfcc_utilst::make_null_check_expr (target_expr), location));
215
218
216
- // create nondet assignment to the target
217
- side_effect_expr_nondett nondet (target_type, location);
218
- havoc_program.add (goto_programt::make_assignment (
219
- dereference_exprt{typecast_exprt::conditional_cast (
220
- target_expr, pointer_type (target_type))},
221
- nondet,
222
- location));
219
+ if (
220
+ ptr_havoc_mode == dfcc_ptr_havoc_modet::INVALID &&
221
+ target_type.id () == ID_pointer)
222
+ {
223
+ // ```
224
+ // DECL *__invalid_ptr;
225
+ // ASSIGN *__havoc_target = __invalid_ptr;
226
+ // DEAD __invalid_ptr;
227
+ // ```
228
+ const auto invalid_ptr_expr = dfcc_utilst::create_symbol (
229
+ goto_model.symbol_table ,
230
+ target_type,
231
+ function_id,
232
+ " __invalid_ptr" ,
233
+ location);
234
+
235
+ havoc_program.add (goto_programt::make_assignment (
236
+ dereference_exprt{typecast_exprt::conditional_cast (
237
+ target_expr, pointer_type (target_type))},
238
+ invalid_ptr_expr,
239
+ location));
240
+ havoc_program.add (
241
+ goto_programt::make_dead (invalid_ptr_expr, location));
242
+ }
243
+ else
244
+ {
245
+ // ```
246
+ // ASSIGN *__havoc_target = nondet(target_type);
247
+ // ```
248
+ side_effect_expr_nondett nondet (target_type, location);
249
+ havoc_program.add (goto_programt::make_assignment (
250
+ dereference_exprt{typecast_exprt::conditional_cast (
251
+ target_expr, pointer_type (target_type))},
252
+ nondet,
253
+ location));
254
+ }
223
255
auto label =
224
256
havoc_program.add (goto_programt::make_dead (target_expr, location));
225
257
goto_instruction->complete_goto (label);
0 commit comments