@@ -11,132 +11,98 @@ Author: Daniel Kroening, kroening@kroening.com
1111
1212#include " goto_convert_class.h"
1313
14+ #include < analyses/natural_loops.h>
15+ #include < unordered_map>
1416#include < util/expr_util.h>
1517#include < util/fresh_symbol.h>
18+ #include < util/mathematical_expr.h>
1619#include < util/pointer_expr.h>
20+ #include < util/replace_expr.h>
1721#include < util/std_expr.h>
1822#include < util/symbol.h>
19- #include < util/mathematical_expr.h>
20- #include < analyses/natural_loops.h>
21- #include < unordered_map>
22- #include < util/replace_expr.h>
23- #include < util/simplify_expr.h>
2423
2524#include " destructor.h"
2625
27- static symbol_exprt find_base_symbol (const exprt &expr)
28- {
29- if (expr.id () == ID_symbol)
30- {
26+ static symbol_exprt find_base_symbol (const exprt &expr) {
27+ if (expr.id () == ID_symbol) {
3128 return to_symbol_expr (expr);
32- }
33- else if (expr.id () == ID_member)
34- {
29+ } else if (expr.id () == ID_member) {
3530 return find_base_symbol (to_member_expr (expr).struct_op ());
36- }
37- else if (expr.id () == ID_index)
38- {
31+ } else if (expr.id () == ID_index) {
3932 return find_base_symbol (to_index_expr (expr).array ());
40- }
41- else if (expr.id () == ID_dereference)
42- {
33+ } else if (expr.id () == ID_dereference) {
4334 return find_base_symbol (to_dereference_expr (expr).pointer ());
44- }
45- else
46- {
35+ } else {
4736 throw " unsupported expression type for finding base symbol" ;
4837 }
4938}
5039
51- static exprt convert_statement_expression (
52- const quantifier_exprt &qex,
53- const code_expressiont &code,
54- const irep_idt &mode,
55- goto_convertt &converter)
56- {
40+ static exprt convert_statement_expression (const quantifier_exprt &qex,
41+ const code_expressiont &code,
42+ const irep_idt &mode,
43+ goto_convertt &converter) {
5744 goto_programt where;
5845 converter.goto_convert (code, where, mode);
5946 where.compute_location_numbers ();
6047
6148 natural_loops_mutablet natural_loops (where);
62- INVARIANT (
63- natural_loops. loop_map . size () == 0 , " quantifier must not contain loops" );
49+ INVARIANT (natural_loops. loop_map . size () == 0 ,
50+ " quantifier must not contain loops" );
6451
6552 // `last` is the instruction corresponding to the last expression in the
6653 // statement expression.
6754 goto_programt::const_targett last = where.instructions .end ();
68- for (goto_programt::const_targett it = where.instructions .begin ();
69- it != where.instructions .end ();
70- ++it)
71- {
55+ for (goto_programt::const_targett it = where.instructions .begin ();
56+ it != where.instructions .end (); ++it) {
7257 // `last` is an other-instruction.
73- if (it->is_other ())
74- {
58+ if (it->is_other ()) {
7559 last = it;
7660 }
7761 }
7862
79- DATA_INVARIANT (
80- last != where.instructions .end (),
81- " expression statements must contain a terminator expression" );
63+ DATA_INVARIANT (last != where.instructions .end (),
64+ " expression statements must contain a terminator expression" );
8265
8366 auto last_expr = to_code_expression (last->get_other ()).expression ();
8467
85- struct pathst
86- {
68+ struct pathst {
8769 // `paths` contains all the `targett` we are iterating over.
8870 std::vector<goto_programt::const_targett> paths;
8971 std::vector<std::pair<exprt, replace_mapt>> path_conditions_and_value_maps;
9072
91- pathst (
92- std::vector<goto_programt::const_targett> paths,
93- std::vector<std::pair<exprt, replace_mapt>>
94- path_conditions_and_value_maps)
95- : paths(paths),
96- path_conditions_and_value_maps (path_conditions_and_value_maps)
97- {
98- }
73+ pathst (std::vector<goto_programt::const_targett> paths,
74+ std::vector<std::pair<exprt, replace_mapt>>
75+ path_conditions_and_value_maps)
76+ : paths(paths),
77+ path_conditions_and_value_maps (path_conditions_and_value_maps) {}
9978
100- bool empty ()
101- {
102- return paths.empty ();
103- }
79+ bool empty () { return paths.empty (); }
10480
105- goto_programt::const_targett &back_it ()
106- {
107- return paths.back ();
108- }
81+ goto_programt::const_targett &back_it () { return paths.back (); }
10982
110- exprt &back_path_condition ()
111- {
83+ exprt &back_path_condition () {
11284 return path_conditions_and_value_maps.back ().first ;
11385 }
11486
115- replace_mapt &back_value_map ()
116- {
87+ replace_mapt &back_value_map () {
11788 return path_conditions_and_value_maps.back ().second ;
11889 }
11990
120- void push_back (
121- goto_programt::const_targett target,
122- exprt path_condition,
123- replace_mapt value_map)
124- {
91+ void push_back (goto_programt::const_targett target, exprt path_condition,
92+ replace_mapt value_map) {
12593 paths.push_back (target);
12694 path_conditions_and_value_maps.push_back (
127- std::make_pair (path_condition, value_map));
95+ std::make_pair (path_condition, value_map));
12896 }
12997
130- void pop_back ()
131- {
98+ void pop_back () {
13299 paths.pop_back ();
133100 path_conditions_and_value_maps.pop_back ();
134101 }
135102 };
136103
137- pathst paths (
138- {1 , where.instructions .begin ()},
139- {1 , std::make_pair (true_exprt (), replace_mapt ())});
104+ pathst paths ({1 , where.instructions .begin ()},
105+ {1 , std::make_pair (true_exprt (), replace_mapt ())});
140106
141107 std::unordered_set<symbol_exprt, irep_hash> declared_symbols;
142108 // All bound variables are local.
@@ -145,36 +111,30 @@ static exprt convert_statement_expression(
145111 exprt res = true_exprt();
146112
147113 // Visit the quantifier body along `paths`.
148- while (!paths.empty())
149- {
114+ while (!paths.empty()) {
150115 auto ¤t_it = paths.back_it ();
151116 auto &path_condition = paths.back_path_condition ();
152117 auto &value_map = paths.back_value_map ();
153- INVARIANT (
154- current_it != where.instructions .end (),
155- " Quantifier body must have a unique end expression." );
118+ INVARIANT (current_it != where.instructions .end (),
119+ " Quantifier body must have a unique end expression." );
156120
157- switch (current_it->type ())
158- {
121+ switch (current_it->type ()) {
159122 // Add all local-declared symbols into `declared_symbols`.
160123 case goto_program_instruction_typet::DECL:
161124 declared_symbols.insert (current_it->decl_symbol ());
162125 break ;
163126
164127 // ASSIGN lhs := rhs
165128 // Add the replace lhr <- value_map(rhs) to the current value_map.
166- case goto_program_instruction_typet::ASSIGN:
167- {
129+ case goto_program_instruction_typet::ASSIGN: {
168130 // Check that if lhs is a declared symbol.
169131 auto lhs = current_it->assign_lhs ();
170- INVARIANT (
171- declared_symbols.count (find_base_symbol (lhs)),
172- " quantifier must not contain side effects" );
132+ INVARIANT (declared_symbols.count (find_base_symbol (lhs)),
133+ " quantifier must not contain side effects" );
173134 exprt rhs = current_it->assign_rhs ();
174135 replace_expr (value_map, rhs);
175136 value_map[lhs] = rhs;
176- }
177- break ;
137+ } break ;
178138
179139 // GOTO label
180140 // -----------
@@ -186,24 +146,18 @@ static exprt convert_statement_expression(
186146 // path_condition && !cond;
187147 // and add a new path starting from label with path condition
188148 // path_condition && cond.
189- case goto_program_instruction_typet::GOTO:
190- {
191- if (!current_it->condition ().is_true ())
192- {
149+ case goto_program_instruction_typet::GOTO: {
150+ if (!current_it->condition ().is_true ()) {
193151 auto next_it = current_it->targets .front ();
194152 exprt copy_path_condition = path_condition;
195153 replace_mapt copy_symbol_map = value_map;
196154 auto copy_condition = current_it->condition ();
197155 path_condition =
198- and_exprt (path_condition, not_exprt (current_it->condition ()));
156+ and_exprt (path_condition, not_exprt (current_it->condition ()));
199157 current_it++;
200- paths.push_back (
201- next_it,
202- and_exprt (copy_path_condition, copy_condition),
203- copy_symbol_map);
204- }
205- else
206- {
158+ paths.push_back (next_it, and_exprt (copy_path_condition, copy_condition),
159+ copy_symbol_map);
160+ } else {
207161 current_it = current_it->targets .front ();
208162 }
209163 continue ;
@@ -212,18 +166,15 @@ static exprt convert_statement_expression(
212166 // EXPRESSION(expr)
213167 // The last instruction is an expression statement.
214168 // We add the predicate path_condition ==> value_map(expr) to res.
215- case goto_program_instruction_typet::OTHER:
216- {
217- if (current_it == last)
218- {
169+ case goto_program_instruction_typet::OTHER: {
170+ if (current_it == last) {
219171 exprt copy_of_last_expr = last_expr;
220172 replace_expr (value_map, copy_of_last_expr);
221173 res = and_exprt (res, implies_exprt (path_condition, copy_of_last_expr));
222174 paths.pop_back ();
223175 continue ;
224176 }
225- }
226- break ;
177+ } break ;
227178
228179 // Ignored instructions.
229180 case goto_program_instruction_typet::ASSERT:
@@ -323,11 +274,10 @@ bool goto_convertt::needs_cleaning(const exprt &expr)
323274 // g1 = (i == 0)
324275 // g2 = (i > 10)
325276 // forall (i : int) (g1 || g2)
326- if (expr.id () == ID_forall || expr.id () == ID_exists)
327- {
277+ if (expr.id () == ID_forall || expr.id () == ID_exists) {
328278 code_expressiont where{to_quantifier_expr (expr).where ()};
329279 // Need cleaning when the quantifier body is a side-effect expression.
330- if (has_subexpr (expr, ID_side_effect))
280+ if (has_subexpr (expr, ID_side_effect))
331281 return true ;
332282
333283 return false ;
@@ -683,23 +633,19 @@ goto_convertt::clean_expr_resultt goto_convertt::clean_expr(
683633 {
684634 quantifier_exprt &qex = to_quantifier_expr (expr);
685635 code_expressiont code{qex.where ()};
686- DATA_INVARIANT (
687- !has_subexpr (expr, ID_side_effect) ||
688- (code.operands ()[0 ].id () == ID_side_effect &&
689- code.operands ()[0 ].get_named_sub ()[ID_statement].id () ==
690- ID_statement_expression),
691- " quantifier must not contain side effects" );
636+ DATA_INVARIANT (!has_subexpr (expr, ID_side_effect) ||
637+ (code.operands ()[0 ].id () == ID_side_effect &&
638+ code.operands ()[0 ].get_named_sub ()[ID_statement].id () ==
639+ ID_statement_expression),
640+ " quantifier must not contain side effects" );
692641
693642 // Handle the case that quantifier body is a statement expression.
694- if (
695- code.operands ()[0 ].id () == ID_side_effect &&
696- code.operands ()[0 ].get_named_sub ()[ID_statement].id () ==
697- ID_statement_expression)
698- {
643+ if (code.operands ()[0 ].id () == ID_side_effect &&
644+ code.operands ()[0 ].get_named_sub ()[ID_statement].id () ==
645+ ID_statement_expression) {
699646 auto res = convert_statement_expression (qex, code, mode, *this );
700647 qex.where () = res;
701648 return clean_expr (res, mode, result_is_used);
702- }
703649 }
704650 else if (expr.id () == ID_address_of)
705651 {
0 commit comments