@@ -19,41 +19,64 @@ 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 (
26
+ goto_modelt &goto_model,
27
+ const optionst &options) : goto_model(goto_model), all_nondet(false )
28
+ {
29
+ typecheck_options (options);
30
+ }
31
31
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
+ }
35
48
36
49
private:
37
50
static bool is_volatile (const namespacet &ns, const typet &src);
38
51
39
- static void nondet_volatile_rhs (
40
- const symbol_tablet &symbol_table,
52
+ void handle_volatile_expression (
41
53
exprt &expr,
42
- havoc_predicatet should_havoc );
54
+ const namespacet &ns );
43
55
44
- static void nondet_volatile_lhs (
56
+ void nondet_volatile_rhs (
45
57
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);
48
67
49
- static void typecheck_model (
68
+ const symbolt &typecheck_variable (
69
+ const irep_idt &id,
70
+ const namespacet &ns);
71
+
72
+ void typecheck_model (
50
73
const irep_idt &id,
51
74
const symbolt &variable,
52
75
const namespacet &ns);
53
76
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 ;
57
80
58
81
// configuration obtained from command line options
59
82
bool all_nondet;
@@ -76,66 +99,76 @@ bool nondet_volatilet::is_volatile(const namespacet &ns, const typet &src)
76
99
return false ;
77
100
}
78
101
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
+
79
119
void nondet_volatilet::nondet_volatile_rhs (
80
120
const symbol_tablet &symbol_table,
81
- exprt &expr,
82
- havoc_predicatet should_havoc)
121
+ exprt &expr)
83
122
{
84
123
Forall_operands (it, expr)
85
- nondet_volatile_rhs (symbol_table, *it, should_havoc );
124
+ nondet_volatile_rhs (symbol_table, *it);
86
125
87
126
if (expr.id ()==ID_symbol ||
88
127
expr.id ()==ID_dereference)
89
128
{
90
129
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);
95
130
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 );
99
134
}
100
135
}
101
136
}
102
137
103
138
void nondet_volatilet::nondet_volatile_lhs (
104
139
const symbol_tablet &symbol_table,
105
- exprt &expr,
106
- havoc_predicatet should_havoc)
140
+ exprt &expr)
107
141
{
108
142
if (expr.id ()==ID_if)
109
143
{
110
- nondet_volatile_rhs (symbol_table, to_if_expr (expr).cond (), should_havoc );
144
+ nondet_volatile_rhs (symbol_table, to_if_expr (expr).cond ());
111
145
nondet_volatile_lhs (
112
- symbol_table, to_if_expr (expr).true_case (), should_havoc );
146
+ symbol_table, to_if_expr (expr).true_case ());
113
147
nondet_volatile_lhs (
114
- symbol_table, to_if_expr (expr).false_case (), should_havoc );
148
+ symbol_table, to_if_expr (expr).false_case ());
115
149
}
116
150
else if (expr.id ()==ID_index)
117
151
{
118
152
nondet_volatile_lhs (
119
- symbol_table, to_index_expr (expr).array (), should_havoc );
153
+ symbol_table, to_index_expr (expr).array ());
120
154
nondet_volatile_rhs (
121
- symbol_table, to_index_expr (expr).index (), should_havoc );
155
+ symbol_table, to_index_expr (expr).index ());
122
156
}
123
157
else if (expr.id ()==ID_member)
124
158
{
125
159
nondet_volatile_lhs (
126
- symbol_table, to_member_expr (expr).struct_op (), should_havoc );
160
+ symbol_table, to_member_expr (expr).struct_op ());
127
161
}
128
162
else if (expr.id ()==ID_dereference)
129
163
{
130
164
nondet_volatile_rhs (
131
- symbol_table, to_dereference_expr (expr).pointer (), should_havoc );
165
+ symbol_table, to_dereference_expr (expr).pointer ());
132
166
}
133
167
}
134
168
135
169
void nondet_volatilet::nondet_volatile (
136
170
symbol_tablet &symbol_table,
137
- goto_programt &goto_program,
138
- havoc_predicatet should_havoc)
171
+ goto_programt &goto_program)
139
172
{
140
173
namespacet ns (symbol_table);
141
174
@@ -146,9 +179,9 @@ void nondet_volatilet::nondet_volatile(
146
179
if (instruction.is_assign ())
147
180
{
148
181
nondet_volatile_rhs (
149
- symbol_table, to_code_assign (instruction.code ).rhs (), should_havoc );
182
+ symbol_table, to_code_assign (instruction.code ).rhs ());
150
183
nondet_volatile_lhs (
151
- symbol_table, to_code_assign (instruction.code ).lhs (), should_havoc );
184
+ symbol_table, to_code_assign (instruction.code ).lhs ());
152
185
}
153
186
else if (instruction.is_function_call ())
154
187
{
@@ -162,16 +195,16 @@ void nondet_volatilet::nondet_volatile(
162
195
it=code_function_call.arguments ().begin ();
163
196
it!=code_function_call.arguments ().end ();
164
197
it++)
165
- nondet_volatile_rhs (symbol_table, *it, should_havoc );
198
+ nondet_volatile_rhs (symbol_table, *it);
166
199
167
200
// 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 ());
169
202
}
170
203
else if (instruction.has_condition ())
171
204
{
172
205
// do condition
173
206
exprt cond = instruction.get_condition ();
174
- nondet_volatile_rhs (symbol_table, cond, should_havoc );
207
+ nondet_volatile_rhs (symbol_table, cond);
175
208
instruction.set_condition (cond);
176
209
}
177
210
}
@@ -246,9 +279,9 @@ void nondet_volatilet::typecheck_model(
246
279
}
247
280
248
281
void nondet_volatilet::typecheck_options (
249
- const goto_modelt &goto_model,
250
282
const optionst &options)
251
283
{
284
+ PRECONDITION (!all_nondet);
252
285
PRECONDITION (nondet_variables.empty ());
253
286
PRECONDITION (variable_models.empty ());
254
287
@@ -317,17 +350,6 @@ void nondet_volatilet::typecheck_options(
317
350
}
318
351
}
319
352
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
-
331
353
void parse_nondet_volatile_options (const cmdlinet &cmdline, optionst &options)
332
354
{
333
355
PRECONDITION (!options.is_set (NONDET_VOLATILE_OPT));
@@ -374,28 +396,6 @@ void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
374
396
375
397
void nondet_volatile (goto_modelt &goto_model, const optionst &options)
376
398
{
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 ();
401
401
}
0 commit comments