@@ -103,6 +103,7 @@ void dfcc_spec_functionst::generate_havoc_function(
103103 havoc_function_id,
104104 original_program,
105105 write_set_symbol.symbol_expr (),
106+ dfcc_ptr_havoc_modet::INVALID,
106107 havoc_program,
107108 nof_targets);
108109
@@ -144,6 +145,7 @@ void dfcc_spec_functionst::generate_havoc_instructions(
144145 const irep_idt &function_id,
145146 const goto_programt &original_program,
146147 const exprt &write_set_to_havoc,
148+ dfcc_ptr_havoc_modet ptr_havoc_mode,
147149 goto_programt &havoc_program,
148150 std::size_t &nof_targets)
149151{
@@ -191,8 +193,9 @@ void dfcc_spec_functionst::generate_havoc_instructions(
191193 // DECL __havoc_target;
192194 // CALL __havoc_target = havoc_hook(set, next_idx);
193195 // 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;
196199 // ```
197200 // declare a local var to store targets havoced via nondet assignment
198201 auto &target_type = get_target_type (ins_it->call_arguments ().at (0 ));
@@ -213,13 +216,42 @@ void dfcc_spec_functionst::generate_havoc_instructions(
213216 havoc_program.add (goto_programt::make_incomplete_goto (
214217 dfcc_utilst::make_null_check_expr (target_expr), location));
215218
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+ }
223255 auto label =
224256 havoc_program.add (goto_programt::make_dead (target_expr, location));
225257 goto_instruction->complete_goto (label);
0 commit comments