@@ -19,39 +19,52 @@ Date: September 2011
19
19
#include < util/string_utils.h>
20
20
#include < util/symbol_table.h>
21
21
22
- using havoc_predicatet = std::function<bool (const exprt &)>;
23
-
24
22
class nondet_volatilet
25
23
{
26
24
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
+ }
31
42
32
- static const symbolt &
33
- typecheck_variable ( const irep_idt &id, const namespacet &ns);
43
+ goto_model. goto_functions . update ();
44
+ }
34
45
35
46
private:
36
47
static bool is_volatile (const namespacet &ns, const typet &src);
37
48
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);
42
52
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);
47
54
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 (
49
61
const irep_idt &id,
50
62
const symbolt &variable,
51
63
const namespacet &ns);
52
64
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;
55
68
56
69
// configuration obtained from command line options
57
70
bool all_nondet;
@@ -74,66 +87,71 @@ bool nondet_volatilet::is_volatile(const namespacet &ns, const typet &src)
74
87
return false ;
75
88
}
76
89
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
+
77
108
void nondet_volatilet::nondet_volatile_rhs (
78
109
const symbol_tablet &symbol_table,
79
- exprt &expr,
80
- havoc_predicatet should_havoc)
110
+ exprt &expr)
81
111
{
82
112
Forall_operands (it, expr)
83
- nondet_volatile_rhs (symbol_table, *it, should_havoc );
113
+ nondet_volatile_rhs (symbol_table, *it);
84
114
85
115
if (expr.id ()==ID_symbol ||
86
116
expr.id ()==ID_dereference)
87
117
{
88
118
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);
93
119
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 );
97
123
}
98
124
}
99
125
}
100
126
101
127
void nondet_volatilet::nondet_volatile_lhs (
102
128
const symbol_tablet &symbol_table,
103
- exprt &expr,
104
- havoc_predicatet should_havoc)
129
+ exprt &expr)
105
130
{
106
131
if (expr.id ()==ID_if)
107
132
{
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 ());
113
136
}
114
137
else if (expr.id ()==ID_index)
115
138
{
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 ());
120
141
}
121
142
else if (expr.id ()==ID_member)
122
143
{
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 ());
125
145
}
126
146
else if (expr.id ()==ID_dereference)
127
147
{
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 ());
130
149
}
131
150
}
132
151
133
152
void nondet_volatilet::nondet_volatile (
134
153
symbol_tablet &symbol_table,
135
- goto_programt &goto_program,
136
- havoc_predicatet should_havoc)
154
+ goto_programt &goto_program)
137
155
{
138
156
namespacet ns (symbol_table);
139
157
@@ -143,10 +161,8 @@ void nondet_volatilet::nondet_volatile(
143
161
144
162
if (instruction.is_assign ())
145
163
{
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 ());
150
166
}
151
167
else if (instruction.is_function_call ())
152
168
{
@@ -160,16 +176,16 @@ void nondet_volatilet::nondet_volatile(
160
176
it=code_function_call.arguments ().begin ();
161
177
it!=code_function_call.arguments ().end ();
162
178
it++)
163
- nondet_volatile_rhs (symbol_table, *it, should_havoc );
179
+ nondet_volatile_rhs (symbol_table, *it);
164
180
165
181
// 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 ());
167
183
}
168
184
else if (instruction.has_condition ())
169
185
{
170
186
// do condition
171
187
exprt cond = instruction.get_condition ();
172
- nondet_volatile_rhs (symbol_table, cond, should_havoc );
188
+ nondet_volatile_rhs (symbol_table, cond);
173
189
instruction.set_condition (cond);
174
190
}
175
191
}
@@ -244,10 +260,9 @@ void nondet_volatilet::typecheck_model(
244
260
}
245
261
}
246
262
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)
250
264
{
265
+ PRECONDITION (!all_nondet);
251
266
PRECONDITION (nondet_variables.empty ());
252
267
PRECONDITION (variable_models.empty ());
253
268
@@ -315,15 +330,6 @@ void nondet_volatilet::typecheck_options(
315
330
}
316
331
}
317
332
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
-
327
333
void parse_nondet_volatile_options (const cmdlinet &cmdline, optionst &options)
328
334
{
329
335
PRECONDITION (!options.is_set (NONDET_VOLATILE_OPT));
@@ -372,28 +378,6 @@ void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
372
378
373
379
void nondet_volatile (goto_modelt &goto_model, const optionst &options)
374
380
{
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 ();
399
383
}
0 commit comments