Skip to content

Commit 782395c

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 11df625 commit 782395c

File tree

1 file changed

+81
-81
lines changed

1 file changed

+81
-81
lines changed

src/goto-instrument/nondet_volatile.cpp

Lines changed: 81 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,64 @@ 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(
26+
goto_modelt &goto_model,
27+
const optionst &options) : goto_model(goto_model), all_nondet(false)
28+
{
29+
typecheck_options(options);
30+
}
3131

32-
static const symbolt &typecheck_variable(
33-
const irep_idt &id,
34-
const namespacet &ns);
32+
void operator()()
33+
{
34+
if(!all_nondet && nondet_variables.empty() && variable_models.empty())
35+
{
36+
return;
37+
}
38+
39+
for(auto &f : goto_model.goto_functions.function_map)
40+
{
41+
nondet_volatile(
42+
goto_model.symbol_table,
43+
f.second.body);
44+
}
45+
46+
goto_model.goto_functions.update();
47+
}
3548

3649
private:
3750
static bool is_volatile(const namespacet &ns, const typet &src);
3851

39-
static void nondet_volatile_rhs(
40-
const symbol_tablet &symbol_table,
52+
void handle_volatile_expression(
4153
exprt &expr,
42-
havoc_predicatet should_havoc);
54+
const namespacet &ns);
4355

44-
static void nondet_volatile_lhs(
56+
void nondet_volatile_rhs(
4557
const symbol_tablet &symbol_table,
46-
exprt &expr,
47-
havoc_predicatet should_havoc);
58+
exprt &expr);
59+
60+
void nondet_volatile_lhs(
61+
const symbol_tablet &symbol_table,
62+
exprt &expr);
63+
64+
void nondet_volatile(
65+
symbol_tablet &symbol_table,
66+
goto_programt &goto_program);
4867

49-
static void typecheck_model(
68+
const symbolt &typecheck_variable(
69+
const irep_idt &id,
70+
const namespacet &ns);
71+
72+
void typecheck_model(
5073
const irep_idt &id,
5174
const symbolt &variable,
5275
const namespacet &ns);
5376

54-
void typecheck_options(
55-
const goto_modelt &goto_model,
56-
const optionst &options);
77+
void typecheck_options(const optionst &options);
78+
79+
goto_modelt &goto_model;
5780

5881
// configuration obtained from command line options
5982
bool all_nondet;
@@ -76,66 +99,76 @@ bool nondet_volatilet::is_volatile(const namespacet &ns, const typet &src)
7699
return false;
77100
}
78101

102+
void nondet_volatilet::handle_volatile_expression(
103+
exprt &expr,
104+
const namespacet &ns)
105+
{
106+
if(all_nondet ||
107+
(expr.id() == ID_symbol &&
108+
nondet_variables.count(to_symbol_expr(expr).get_identifier()) != 0))
109+
{
110+
typet t = expr.type();
111+
t.remove(ID_C_volatile);
112+
113+
// replace by nondet
114+
side_effect_expr_nondett nondet_expr(t, expr.source_location());
115+
expr.swap(nondet_expr);
116+
}
117+
}
118+
79119
void nondet_volatilet::nondet_volatile_rhs(
80120
const symbol_tablet &symbol_table,
81-
exprt &expr,
82-
havoc_predicatet should_havoc)
121+
exprt &expr)
83122
{
84123
Forall_operands(it, expr)
85-
nondet_volatile_rhs(symbol_table, *it, should_havoc);
124+
nondet_volatile_rhs(symbol_table, *it);
86125

87126
if(expr.id()==ID_symbol ||
88127
expr.id()==ID_dereference)
89128
{
90129
const namespacet ns(symbol_table);
91-
if(is_volatile(ns, expr.type()) && should_havoc(expr))
92-
{
93-
typet t=expr.type();
94-
t.remove(ID_C_volatile);
95130

96-
// replace by nondet
97-
side_effect_expr_nondett nondet_expr(t, expr.source_location());
98-
expr.swap(nondet_expr);
131+
if(is_volatile(ns, expr.type()))
132+
{
133+
handle_volatile_expression(expr, ns);
99134
}
100135
}
101136
}
102137

103138
void nondet_volatilet::nondet_volatile_lhs(
104139
const symbol_tablet &symbol_table,
105-
exprt &expr,
106-
havoc_predicatet should_havoc)
140+
exprt &expr)
107141
{
108142
if(expr.id()==ID_if)
109143
{
110-
nondet_volatile_rhs(symbol_table, to_if_expr(expr).cond(), should_havoc);
144+
nondet_volatile_rhs(symbol_table, to_if_expr(expr).cond());
111145
nondet_volatile_lhs(
112-
symbol_table, to_if_expr(expr).true_case(), should_havoc);
146+
symbol_table, to_if_expr(expr).true_case());
113147
nondet_volatile_lhs(
114-
symbol_table, to_if_expr(expr).false_case(), should_havoc);
148+
symbol_table, to_if_expr(expr).false_case());
115149
}
116150
else if(expr.id()==ID_index)
117151
{
118152
nondet_volatile_lhs(
119-
symbol_table, to_index_expr(expr).array(), should_havoc);
153+
symbol_table, to_index_expr(expr).array());
120154
nondet_volatile_rhs(
121-
symbol_table, to_index_expr(expr).index(), should_havoc);
155+
symbol_table, to_index_expr(expr).index());
122156
}
123157
else if(expr.id()==ID_member)
124158
{
125159
nondet_volatile_lhs(
126-
symbol_table, to_member_expr(expr).struct_op(), should_havoc);
160+
symbol_table, to_member_expr(expr).struct_op());
127161
}
128162
else if(expr.id()==ID_dereference)
129163
{
130164
nondet_volatile_rhs(
131-
symbol_table, to_dereference_expr(expr).pointer(), should_havoc);
165+
symbol_table, to_dereference_expr(expr).pointer());
132166
}
133167
}
134168

135169
void nondet_volatilet::nondet_volatile(
136170
symbol_tablet &symbol_table,
137-
goto_programt &goto_program,
138-
havoc_predicatet should_havoc)
171+
goto_programt &goto_program)
139172
{
140173
namespacet ns(symbol_table);
141174

@@ -146,9 +179,9 @@ void nondet_volatilet::nondet_volatile(
146179
if(instruction.is_assign())
147180
{
148181
nondet_volatile_rhs(
149-
symbol_table, to_code_assign(instruction.code).rhs(), should_havoc);
182+
symbol_table, to_code_assign(instruction.code).rhs());
150183
nondet_volatile_lhs(
151-
symbol_table, to_code_assign(instruction.code).lhs(), should_havoc);
184+
symbol_table, to_code_assign(instruction.code).lhs());
152185
}
153186
else if(instruction.is_function_call())
154187
{
@@ -162,16 +195,16 @@ void nondet_volatilet::nondet_volatile(
162195
it=code_function_call.arguments().begin();
163196
it!=code_function_call.arguments().end();
164197
it++)
165-
nondet_volatile_rhs(symbol_table, *it, should_havoc);
198+
nondet_volatile_rhs(symbol_table, *it);
166199

167200
// do return value
168-
nondet_volatile_lhs(symbol_table, code_function_call.lhs(), should_havoc);
201+
nondet_volatile_lhs(symbol_table, code_function_call.lhs());
169202
}
170203
else if(instruction.has_condition())
171204
{
172205
// do condition
173206
exprt cond = instruction.get_condition();
174-
nondet_volatile_rhs(symbol_table, cond, should_havoc);
207+
nondet_volatile_rhs(symbol_table, cond);
175208
instruction.set_condition(cond);
176209
}
177210
}
@@ -246,9 +279,9 @@ void nondet_volatilet::typecheck_model(
246279
}
247280

248281
void nondet_volatilet::typecheck_options(
249-
const goto_modelt &goto_model,
250282
const optionst &options)
251283
{
284+
PRECONDITION(!all_nondet);
252285
PRECONDITION(nondet_variables.empty());
253286
PRECONDITION(variable_models.empty());
254287

@@ -317,17 +350,6 @@ void nondet_volatilet::typecheck_options(
317350
}
318351
}
319352

320-
void nondet_volatile(goto_modelt &goto_model, havoc_predicatet should_havoc)
321-
{
322-
Forall_goto_functions(f_it, goto_model.goto_functions)
323-
nondet_volatilet::nondet_volatile(
324-
goto_model.symbol_table,
325-
f_it->second.body,
326-
should_havoc);
327-
328-
goto_model.goto_functions.update();
329-
}
330-
331353
void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
332354
{
333355
PRECONDITION(!options.is_set(NONDET_VOLATILE_OPT));
@@ -374,28 +396,6 @@ void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
374396

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

0 commit comments

Comments
 (0)