@@ -160,13 +160,17 @@ class empty_replace_function_bodiest : public replace_function_bodiest
160160 }
161161};
162162
163- class havoc_replace_function_bodiest : public replace_function_bodiest
163+ class havoc_replace_function_bodiest : public replace_function_bodiest ,
164+ private messaget
164165{
165166public:
166167 havoc_replace_function_bodiest (
167168 std::vector<irep_idt> globals_to_havoc,
168- std::regex parameters_to_havoc)
169- : globals_to_havoc(std::move(globals_to_havoc)),
169+ std::regex parameters_to_havoc,
170+ message_handlert &message_handler)
171+ : replace_function_bodiest(),
172+ messaget (message_handler),
173+ globals_to_havoc(std::move(globals_to_havoc)),
170174 parameters_to_havoc(std::move(parameters_to_havoc))
171175 {
172176 }
@@ -190,26 +194,35 @@ class havoc_replace_function_bodiest : public replace_function_bodiest
190194 {
191195 if (
192196 parameter.type ().id () == ID_pointer &&
193- !is_constant_or_has_constant_components (
194- parameter.type ().subtype (), ns) &&
195197 std::regex_match (
196198 id2string (parameter.get_base_name ()), parameters_to_havoc))
197199 {
198- // if (param != nullptr) { *param = nondet(); }
199- auto goto_instruction = add_instruction ();
200- auto assign_instruction = add_instruction ();
201- auto label_instruction = add_instruction ();
202- goto_instruction->make_goto (
203- label_instruction,
204- equal_exprt (
205- symbol_exprt (parameter.get_identifier (), parameter.type ()),
206- null_pointer_exprt (to_pointer_type (parameter.type ()))));
207- assign_instruction->make_assignment ();
208- assign_instruction->code = code_assignt (
209- dereference_exprt (
210- symbol_exprt (parameter.get_identifier (), parameter.type ())),
211- side_effect_expr_nondett (parameter.type ().subtype ()));
212- label_instruction->make_skip ();
200+ if (
201+ !is_constant_or_has_constant_components (
202+ parameter.type ().subtype (), ns))
203+ {
204+ // if (param != nullptr) { *param = nondet(); }
205+ auto goto_instruction = add_instruction ();
206+ auto assign_instruction = add_instruction ();
207+ auto label_instruction = add_instruction ();
208+ goto_instruction->make_goto (
209+ label_instruction,
210+ equal_exprt (
211+ symbol_exprt (parameter.get_identifier (), parameter.type ()),
212+ null_pointer_exprt (to_pointer_type (parameter.type ()))));
213+ assign_instruction->make_assignment ();
214+ assign_instruction->code = code_assignt (
215+ dereference_exprt (
216+ symbol_exprt (parameter.get_identifier (), parameter.type ())),
217+ side_effect_expr_nondett (parameter.type ().subtype ()));
218+ label_instruction->make_skip ();
219+ }
220+ else if (!parameter.type ().subtype ().get_bool (ID_C_constant))
221+ {
222+ warning () << " warning: not havoccing non-const pointer parameter '"
223+ << parameter.get_base_name () << " ' of " << function_name
224+ << " because it has const members" << messaget::eom;
225+ }
213226 }
214227 }
215228
@@ -249,12 +262,13 @@ class replace_function_bodies_errort : public std::runtime_error
249262
250263std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory (
251264 const std::string &options,
252- const symbol_tablet &symbol_table)
265+ const symbol_tablet &symbol_table,
266+ message_handlert &message_handler)
253267{
254268 if (options.empty () || options == " nondet-return" )
255269 {
256270 return util_make_unique<havoc_replace_function_bodiest>(
257- std::vector<irep_idt>{}, std::regex{});
271+ std::vector<irep_idt>{}, std::regex{}, message_handler );
258272 }
259273
260274 if (options == " assume-false" )
@@ -308,18 +322,27 @@ std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory(
308322 }
309323 std::vector<irep_idt> globals_to_havoc;
310324 namespacet ns (symbol_table);
325+ messaget messages (message_handler);
311326 for (auto const &symbol : symbol_table.symbols )
312327 {
313328 if (
314329 symbol.second .is_lvalue && symbol.second .is_static_lifetime &&
315- !is_constant_or_has_constant_components (symbol.second .type , ns) &&
316330 std::regex_match (id2string (symbol.first ), globals_regex))
317331 {
318- globals_to_havoc.push_back (symbol.first );
332+ if (!is_constant_or_has_constant_components (symbol.second .type , ns))
333+ {
334+ globals_to_havoc.push_back (symbol.first );
335+ }
336+ else if (!symbol.second .type .get_bool (ID_C_constant))
337+ {
338+ messages.warning () << " warning: not havoccing non-const global '"
339+ << symbol.first << " ' because it has const members"
340+ << messaget::eom;
341+ }
319342 }
320343 }
321344 return util_make_unique<havoc_replace_function_bodiest>(
322- std::move (globals_to_havoc), std::move (params_regex));
345+ std::move (globals_to_havoc), std::move (params_regex), message_handler );
323346 }
324347 throw replace_function_bodies_errort (" Can't parse \" " + options + " \" " );
325348}
@@ -328,7 +351,8 @@ std::unique_ptr<replace_function_bodiest> replace_function_body_options_factory(
328351// / \see replace_function_bodies() for information of how the cmdline is parsed
329352replace_function_body_optionst parse_replace_function_body_optionst (
330353 const cmdlinet &cmdline,
331- const symbol_tablet &symbol_table)
354+ const symbol_tablet &symbol_table,
355+ message_handlert &message_handler)
332356{
333357 if (
334358 cmdline.isset (" replace-function-body" ) &&
@@ -343,7 +367,9 @@ replace_function_body_optionst parse_replace_function_body_optionst(
343367 only_generate ? cmdline.get_value (" generate-function-body" )
344368 : cmdline.get_value (" replace-function-body" ));
345369 auto replace_function_bodies = replace_function_body_options_factory (
346- cmdline.get_value (" replace-function-body-options" ), symbol_table);
370+ cmdline.get_value (" replace-function-body-options" ),
371+ symbol_table,
372+ message_handler);
347373 return {function_regex, only_generate, std::move (replace_function_bodies)};
348374}
349375
@@ -430,7 +456,7 @@ void replace_function_bodies(
430456 {
431457 messaget messages (message_handler);
432458 messages.warning ()
433- << " Replace function bodies: No function name matched regex"
459+ << " warning: Replace function bodies: No function name matched regex"
434460 << messaget::eom;
435461 }
436462}
0 commit comments