Skip to content

Commit 47bb11e

Browse files
committed
Refactor existing nondet volatile code
Refactor the code such as to allow later addition of new feature to selectively provide models for volatile reads
1 parent 4b841c7 commit 47bb11e

File tree

1 file changed

+73
-89
lines changed

1 file changed

+73
-89
lines changed

src/goto-instrument/nondet_volatile.cpp

Lines changed: 73 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,52 @@ Date: September 2011
1919
#include <util/string_utils.h>
2020
#include <util/symbol_table.h>
2121

22-
using havoc_predicatet = std::function<bool(const exprt &)>;
23-
2422
class nondet_volatilet
2523
{
2624
public:
27-
static void nondet_volatile(
28-
symbol_tablet &symbol_table,
29-
goto_programt &goto_program,
30-
havoc_predicatet should_havoc);
25+
nondet_volatilet(goto_modelt &goto_model, const optionst &options)
26+
: goto_model(goto_model), all_nondet(false)
27+
{
28+
typecheck_options(options);
29+
}
30+
31+
void operator()()
32+
{
33+
if(!all_nondet && nondet_variables.empty() && variable_models.empty())
34+
{
35+
return;
36+
}
37+
38+
for(auto &f : goto_model.goto_functions.function_map)
39+
{
40+
nondet_volatile(goto_model.symbol_table, f.second.body);
41+
}
3142

32-
static const symbolt &
33-
typecheck_variable(const irep_idt &id, const namespacet &ns);
43+
goto_model.goto_functions.update();
44+
}
3445

3546
private:
3647
static bool is_volatile(const namespacet &ns, const typet &src);
3748

38-
static void nondet_volatile_rhs(
39-
const symbol_tablet &symbol_table,
40-
exprt &expr,
41-
havoc_predicatet should_havoc);
49+
void handle_volatile_expression(exprt &expr, const namespacet &ns);
50+
51+
void nondet_volatile_rhs(const symbol_tablet &symbol_table, exprt &expr);
4252

43-
static void nondet_volatile_lhs(
44-
const symbol_tablet &symbol_table,
45-
exprt &expr,
46-
havoc_predicatet should_havoc);
53+
void nondet_volatile_lhs(const symbol_tablet &symbol_table, exprt &expr);
4754

48-
static void typecheck_model(
55+
void
56+
nondet_volatile(symbol_tablet &symbol_table, goto_programt &goto_program);
57+
58+
const symbolt &typecheck_variable(const irep_idt &id, const namespacet &ns);
59+
60+
void typecheck_model(
4961
const irep_idt &id,
5062
const symbolt &variable,
5163
const namespacet &ns);
5264

53-
void
54-
typecheck_options(const goto_modelt &goto_model, const optionst &options);
65+
void typecheck_options(const optionst &options);
66+
67+
goto_modelt &goto_model;
5568

5669
// configuration obtained from command line options
5770
bool all_nondet;
@@ -74,66 +87,71 @@ bool nondet_volatilet::is_volatile(const namespacet &ns, const typet &src)
7487
return false;
7588
}
7689

90+
void nondet_volatilet::handle_volatile_expression(
91+
exprt &expr,
92+
const namespacet &ns)
93+
{
94+
if(
95+
all_nondet ||
96+
(expr.id() == ID_symbol &&
97+
nondet_variables.count(to_symbol_expr(expr).get_identifier()) != 0))
98+
{
99+
typet t = expr.type();
100+
t.remove(ID_C_volatile);
101+
102+
// replace by nondet
103+
side_effect_expr_nondett nondet_expr(t, expr.source_location());
104+
expr.swap(nondet_expr);
105+
}
106+
}
107+
77108
void nondet_volatilet::nondet_volatile_rhs(
78109
const symbol_tablet &symbol_table,
79-
exprt &expr,
80-
havoc_predicatet should_havoc)
110+
exprt &expr)
81111
{
82112
Forall_operands(it, expr)
83-
nondet_volatile_rhs(symbol_table, *it, should_havoc);
113+
nondet_volatile_rhs(symbol_table, *it);
84114

85115
if(expr.id()==ID_symbol ||
86116
expr.id()==ID_dereference)
87117
{
88118
const namespacet ns(symbol_table);
89-
if(is_volatile(ns, expr.type()) && should_havoc(expr))
90-
{
91-
typet t=expr.type();
92-
t.remove(ID_C_volatile);
93119

94-
// replace by nondet
95-
side_effect_expr_nondett nondet_expr(t, expr.source_location());
96-
expr.swap(nondet_expr);
120+
if(is_volatile(ns, expr.type()))
121+
{
122+
handle_volatile_expression(expr, ns);
97123
}
98124
}
99125
}
100126

101127
void nondet_volatilet::nondet_volatile_lhs(
102128
const symbol_tablet &symbol_table,
103-
exprt &expr,
104-
havoc_predicatet should_havoc)
129+
exprt &expr)
105130
{
106131
if(expr.id()==ID_if)
107132
{
108-
nondet_volatile_rhs(symbol_table, to_if_expr(expr).cond(), should_havoc);
109-
nondet_volatile_lhs(
110-
symbol_table, to_if_expr(expr).true_case(), should_havoc);
111-
nondet_volatile_lhs(
112-
symbol_table, to_if_expr(expr).false_case(), should_havoc);
133+
nondet_volatile_rhs(symbol_table, to_if_expr(expr).cond());
134+
nondet_volatile_lhs(symbol_table, to_if_expr(expr).true_case());
135+
nondet_volatile_lhs(symbol_table, to_if_expr(expr).false_case());
113136
}
114137
else if(expr.id()==ID_index)
115138
{
116-
nondet_volatile_lhs(
117-
symbol_table, to_index_expr(expr).array(), should_havoc);
118-
nondet_volatile_rhs(
119-
symbol_table, to_index_expr(expr).index(), should_havoc);
139+
nondet_volatile_lhs(symbol_table, to_index_expr(expr).array());
140+
nondet_volatile_rhs(symbol_table, to_index_expr(expr).index());
120141
}
121142
else if(expr.id()==ID_member)
122143
{
123-
nondet_volatile_lhs(
124-
symbol_table, to_member_expr(expr).struct_op(), should_havoc);
144+
nondet_volatile_lhs(symbol_table, to_member_expr(expr).struct_op());
125145
}
126146
else if(expr.id()==ID_dereference)
127147
{
128-
nondet_volatile_rhs(
129-
symbol_table, to_dereference_expr(expr).pointer(), should_havoc);
148+
nondet_volatile_rhs(symbol_table, to_dereference_expr(expr).pointer());
130149
}
131150
}
132151

133152
void nondet_volatilet::nondet_volatile(
134153
symbol_tablet &symbol_table,
135-
goto_programt &goto_program,
136-
havoc_predicatet should_havoc)
154+
goto_programt &goto_program)
137155
{
138156
namespacet ns(symbol_table);
139157

@@ -143,10 +161,8 @@ void nondet_volatilet::nondet_volatile(
143161

144162
if(instruction.is_assign())
145163
{
146-
nondet_volatile_rhs(
147-
symbol_table, to_code_assign(instruction.code).rhs(), should_havoc);
148-
nondet_volatile_lhs(
149-
symbol_table, to_code_assign(instruction.code).lhs(), should_havoc);
164+
nondet_volatile_rhs(symbol_table, to_code_assign(instruction.code).rhs());
165+
nondet_volatile_lhs(symbol_table, to_code_assign(instruction.code).lhs());
150166
}
151167
else if(instruction.is_function_call())
152168
{
@@ -160,16 +176,16 @@ void nondet_volatilet::nondet_volatile(
160176
it=code_function_call.arguments().begin();
161177
it!=code_function_call.arguments().end();
162178
it++)
163-
nondet_volatile_rhs(symbol_table, *it, should_havoc);
179+
nondet_volatile_rhs(symbol_table, *it);
164180

165181
// do return value
166-
nondet_volatile_lhs(symbol_table, code_function_call.lhs(), should_havoc);
182+
nondet_volatile_lhs(symbol_table, code_function_call.lhs());
167183
}
168184
else if(instruction.has_condition())
169185
{
170186
// do condition
171187
exprt cond = instruction.get_condition();
172-
nondet_volatile_rhs(symbol_table, cond, should_havoc);
188+
nondet_volatile_rhs(symbol_table, cond);
173189
instruction.set_condition(cond);
174190
}
175191
}
@@ -244,10 +260,9 @@ void nondet_volatilet::typecheck_model(
244260
}
245261
}
246262

247-
void nondet_volatilet::typecheck_options(
248-
const goto_modelt &goto_model,
249-
const optionst &options)
263+
void nondet_volatilet::typecheck_options(const optionst &options)
250264
{
265+
PRECONDITION(!all_nondet);
251266
PRECONDITION(nondet_variables.empty());
252267
PRECONDITION(variable_models.empty());
253268

@@ -315,15 +330,6 @@ void nondet_volatilet::typecheck_options(
315330
}
316331
}
317332

318-
void nondet_volatile(goto_modelt &goto_model, havoc_predicatet should_havoc)
319-
{
320-
Forall_goto_functions(f_it, goto_model.goto_functions)
321-
nondet_volatilet::nondet_volatile(
322-
goto_model.symbol_table, f_it->second.body, should_havoc);
323-
324-
goto_model.goto_functions.update();
325-
}
326-
327333
void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
328334
{
329335
PRECONDITION(!options.is_set(NONDET_VOLATILE_OPT));
@@ -372,28 +378,6 @@ void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
372378

373379
void nondet_volatile(goto_modelt &goto_model, const optionst &options)
374380
{
375-
if(options.get_bool_option(NONDET_VOLATILE_OPT))
376-
{
377-
nondet_volatile(goto_model);
378-
}
379-
else if(options.is_set(NONDET_VOLATILE_VARIABLE_OPT))
380-
{
381-
const auto &variable_list =
382-
options.get_list_option(NONDET_VOLATILE_VARIABLE_OPT);
383-
384-
std::set<irep_idt> variables(variable_list.begin(), variable_list.end());
385-
const namespacet ns(goto_model.symbol_table);
386-
387-
for(const auto &id : variables)
388-
{
389-
nondet_volatilet::typecheck_variable(id, ns);
390-
}
391-
392-
auto should_havoc = [&variables](const exprt &expr) {
393-
return expr.id() == ID_symbol &&
394-
variables.count(to_symbol_expr(expr).get_identifier()) != 0;
395-
};
396-
397-
nondet_volatile(goto_model, should_havoc);
398-
}
381+
nondet_volatilet nv(goto_model, options);
382+
nv();
399383
}

0 commit comments

Comments
 (0)