@@ -16,6 +16,7 @@ Author: Daniel Kroening, kroening@kroening.com
1616
1717#include < util/base_exceptions.h>
1818#include < util/exception_utils.h>
19+ #include < util/expr_util.h>
1920#include < util/invariant.h>
2021#include < util/prefix.h>
2122#include < util/std_expr.h>
@@ -79,122 +80,6 @@ void goto_symex_statet::level1t::operator()(ssa_exprt &ssa_expr)
7980 ssa_expr.set_level_1 (it->second .second );
8081}
8182
82- // / This function determines what expressions are to be propagated as
83- // / "constants"
84- bool goto_symex_statet::constant_propagation (const exprt &expr) const
85- {
86- if (expr.is_constant ())
87- return true ;
88-
89- if (expr.id ()==ID_address_of)
90- {
91- const address_of_exprt &address_of_expr=to_address_of_expr (expr);
92-
93- return constant_propagation_reference (address_of_expr.object ());
94- }
95- else if (expr.id ()==ID_typecast)
96- {
97- const typecast_exprt &typecast_expr=to_typecast_expr (expr);
98-
99- return constant_propagation (typecast_expr.op ());
100- }
101- else if (expr.id ()==ID_plus)
102- {
103- forall_operands (it, expr)
104- if (!constant_propagation (*it))
105- return false ;
106-
107- return true ;
108- }
109- else if (expr.id ()==ID_mult)
110- {
111- // propagate stuff with sizeof in it
112- forall_operands (it, expr)
113- {
114- if (it->find (ID_C_c_sizeof_type).is_not_nil ())
115- return true ;
116- else if (!constant_propagation (*it))
117- return false ;
118- }
119-
120- return true ;
121- }
122- else if (expr.id ()==ID_array)
123- {
124- forall_operands (it, expr)
125- if (!constant_propagation (*it))
126- return false ;
127-
128- return true ;
129- }
130- else if (expr.id ()==ID_array_of)
131- {
132- return constant_propagation (expr.op0 ());
133- }
134- else if (expr.id ()==ID_with)
135- {
136- // this is bad
137- /*
138- forall_operands(it, expr)
139- if(!constant_propagation(expr.op0()))
140- return false;
141-
142- return true;
143- */
144- return false ;
145- }
146- else if (expr.id ()==ID_struct)
147- {
148- forall_operands (it, expr)
149- if (!constant_propagation (*it))
150- return false ;
151-
152- return true ;
153- }
154- else if (expr.id ()==ID_union)
155- {
156- forall_operands (it, expr)
157- if (!constant_propagation (*it))
158- return false ;
159-
160- return true ;
161- }
162- // byte_update works, byte_extract may be out-of-bounds
163- else if (expr.id ()==ID_byte_update_big_endian ||
164- expr.id ()==ID_byte_update_little_endian)
165- {
166- forall_operands (it, expr)
167- if (!constant_propagation (*it))
168- return false ;
169-
170- return true ;
171- }
172-
173- return false ;
174- }
175-
176- // / this function determines which reference-typed expressions are constant
177- bool goto_symex_statet::constant_propagation_reference (const exprt &expr) const
178- {
179- if (expr.id ()==ID_symbol)
180- return true ;
181- else if (expr.id ()==ID_index)
182- {
183- const index_exprt &index_expr=to_index_expr (expr);
184-
185- return constant_propagation_reference (index_expr.array ()) &&
186- constant_propagation (index_expr.index ());
187- }
188- else if (expr.id ()==ID_member)
189- {
190- return constant_propagation_reference (to_member_expr (expr).compound ());
191- }
192- else if (expr.id ()==ID_string_constant)
193- return true ;
194-
195- return false ;
196- }
197-
19883// / write to a variable
19984static bool check_renaming (const exprt &expr);
20085
@@ -297,6 +182,41 @@ static void assert_l2_renaming(const exprt &expr)
297182 #endif
298183}
299184
185+ class goto_symex_is_constantt : public is_constantt
186+ {
187+ protected:
188+ bool is_constant (const exprt &expr) const override
189+ {
190+ if (expr.id () == ID_mult)
191+ {
192+ // propagate stuff with sizeof in it
193+ forall_operands (it, expr)
194+ {
195+ if (it->find (ID_C_c_sizeof_type).is_not_nil ())
196+ return true ;
197+ else if (!is_constant (*it))
198+ return false ;
199+ }
200+
201+ return true ;
202+ }
203+ else if (expr.id () == ID_with)
204+ {
205+ // this is bad
206+ /*
207+ forall_operands(it, expr)
208+ if(!is_constant(expr.op0()))
209+ return false;
210+
211+ return true;
212+ */
213+ return false ;
214+ }
215+
216+ return is_constantt::is_constant (expr);
217+ }
218+ };
219+
300220void goto_symex_statet::assignment (
301221 ssa_exprt &lhs, // L0/L1
302222 const exprt &rhs, // L2
@@ -341,7 +261,7 @@ void goto_symex_statet::assignment(
341261
342262 // for value propagation -- the RHS is L2
343263
344- if (!is_shared && record_value && constant_propagation (rhs))
264+ if (!is_shared && record_value && goto_symex_is_constantt () (rhs))
345265 propagation.values [l1_identifier]=rhs;
346266 else
347267 propagation.remove (l1_identifier);
0 commit comments