@@ -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-
2422class nondet_volatilet
2523{
2624public:
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
3546private:
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+
77108void 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
101127void 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
133152void 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-
327333void 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
373379void 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