|
16 | 16 |
|
17 | 17 | #include <util/base_exceptions.h>
|
18 | 18 | #include <util/exception_utils.h>
|
| 19 | +#include <util/expr_util.h> |
19 | 20 | #include <util/invariant.h>
|
20 | 21 | #include <util/prefix.h>
|
21 | 22 | #include <util/std_expr.h>
|
@@ -79,122 +80,6 @@ void goto_symex_statet::level1t::operator()(ssa_exprt &ssa_expr)
|
79 | 80 | ssa_expr.set_level_1(it->second.second);
|
80 | 81 | }
|
81 | 82 |
|
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 |
| - |
198 | 83 | /// write to a variable
|
199 | 84 | static bool check_renaming(const exprt &expr);
|
200 | 85 |
|
@@ -297,6 +182,41 @@ static void assert_l2_renaming(const exprt &expr)
|
297 | 182 | #endif
|
298 | 183 | }
|
299 | 184 |
|
| 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 | + |
300 | 220 | void goto_symex_statet::assignment(
|
301 | 221 | ssa_exprt &lhs, // L0/L1
|
302 | 222 | const exprt &rhs, // L2
|
@@ -341,7 +261,7 @@ void goto_symex_statet::assignment(
|
341 | 261 |
|
342 | 262 | // for value propagation -- the RHS is L2
|
343 | 263 |
|
344 |
| - if(!is_shared && record_value && constant_propagation(rhs)) |
| 264 | + if(!is_shared && record_value && goto_symex_is_constantt()(rhs)) |
345 | 265 | propagation.values[l1_identifier]=rhs;
|
346 | 266 | else
|
347 | 267 | propagation.remove(l1_identifier);
|
|
0 commit comments