Skip to content

Commit 0ae6a9f

Browse files
WIP Add regression test for struct with const members
1 parent 9f6c032 commit 0ae6a9f

File tree

5 files changed

+85
-31
lines changed

5 files changed

+85
-31
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <assert.h>
2+
3+
struct WithConstMember
4+
{
5+
int non_const;
6+
const int is_const;
7+
};
8+
9+
struct WithConstMember globalStruct = {10, 20};
10+
void havoc_struct(struct WithConstMember *s);
11+
12+
int main(void)
13+
{
14+
struct WithConstMember paramStruct = {11, 21};
15+
havoc_struct(&paramStruct);
16+
assert(globalStruct.non_const == 10);
17+
assert(globalStruct.is_const == 20);
18+
assert(paramStruct.non_const == 11);
19+
assert(paramStruct.is_const == 21);
20+
return 0;
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--replace-function-body 'havoc_struct' --replace-function-body-options 'havoc,params:.*,globals:(?!__).*'
4+
^SIGNAL=0$
5+
^EXIT=0$
6+
^VERIFICATION SUCCESSFUL$

src/goto-instrument/goto_instrument_parse_options.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1452,8 +1452,8 @@ void goto_instrument_parse_optionst::instrument_goto_program()
14521452
cmdline.isset("replace-function-body") ||
14531453
cmdline.isset("generate-function-body"))
14541454
{
1455-
auto replace_options =
1456-
parse_replace_function_body_optionst(cmdline, goto_model.symbol_table);
1455+
auto replace_options = parse_replace_function_body_optionst(
1456+
cmdline, goto_model.symbol_table, *message_handler);
14571457
status() << (replace_options.only_generate ? "Generating" : "Replacing")
14581458
<< " function bodies" << eom;
14591459
replace_function_bodies(goto_model, replace_options, *message_handler);

src/goto-programs/replace_function_bodies.cpp

+54-28
Original file line numberDiff line numberDiff line change
@@ -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
{
165166
public:
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

250263
std::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
329352
replace_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
}

src/goto-programs/replace_function_bodies.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ struct replace_function_body_optionst
9090

9191
replace_function_body_optionst parse_replace_function_body_optionst(
9292
const cmdlinet &cmdline,
93-
const symbol_tablet &symbol_table);
93+
const symbol_tablet &symbol_table,
94+
message_handlert &message_handler);
9495

9596
void replace_function_bodies(
9697
goto_modelt &model,

0 commit comments

Comments
 (0)