|
17 | 17 |
|
18 | 18 | #include <util/as_const.h> |
19 | 19 | #include <util/base_exceptions.h> |
| 20 | +#include <util/byte_operators.h> |
20 | 21 | #include <util/exception_utils.h> |
21 | 22 | #include <util/expr_util.h> |
22 | 23 | #include <util/format.h> |
@@ -48,90 +49,6 @@ goto_symex_statet::goto_symex_statet( |
48 | 49 |
|
49 | 50 | goto_symex_statet::~goto_symex_statet()=default; |
50 | 51 |
|
51 | | -/// Check that \p expr is correctly renamed to level 2 and return true in case |
52 | | -/// an error is detected. |
53 | | -static bool check_renaming(const exprt &expr); |
54 | | - |
55 | | -static bool check_renaming(const typet &type) |
56 | | -{ |
57 | | - if(type.id()==ID_array) |
58 | | - return check_renaming(to_array_type(type).size()); |
59 | | - else if(type.id() == ID_struct || type.id() == ID_union) |
60 | | - { |
61 | | - for(const auto &c : to_struct_union_type(type).components()) |
62 | | - if(check_renaming(c.type())) |
63 | | - return true; |
64 | | - } |
65 | | - else if(type.has_subtype()) |
66 | | - return check_renaming(to_type_with_subtype(type).subtype()); |
67 | | - |
68 | | - return false; |
69 | | -} |
70 | | - |
71 | | -static bool check_renaming_l1(const exprt &expr) |
72 | | -{ |
73 | | - if(check_renaming(expr.type())) |
74 | | - return true; |
75 | | - |
76 | | - if(expr.id()==ID_symbol) |
77 | | - { |
78 | | - const auto &type = expr.type(); |
79 | | - if(!expr.get_bool(ID_C_SSA_symbol)) |
80 | | - return type.id() != ID_code && type.id() != ID_mathematical_function; |
81 | | - if(!to_ssa_expr(expr).get_level_2().empty()) |
82 | | - return true; |
83 | | - if(to_ssa_expr(expr).get_original_expr().type() != type) |
84 | | - return true; |
85 | | - } |
86 | | - else |
87 | | - { |
88 | | - forall_operands(it, expr) |
89 | | - if(check_renaming_l1(*it)) |
90 | | - return true; |
91 | | - } |
92 | | - |
93 | | - return false; |
94 | | -} |
95 | | - |
96 | | -static bool check_renaming(const exprt &expr) |
97 | | -{ |
98 | | - if(check_renaming(expr.type())) |
99 | | - return true; |
100 | | - |
101 | | - if( |
102 | | - expr.id() == ID_address_of && |
103 | | - to_address_of_expr(expr).object().id() == ID_symbol) |
104 | | - { |
105 | | - return check_renaming_l1(to_address_of_expr(expr).object()); |
106 | | - } |
107 | | - else if( |
108 | | - expr.id() == ID_address_of && |
109 | | - to_address_of_expr(expr).object().id() == ID_index) |
110 | | - { |
111 | | - const auto index_expr = to_index_expr(to_address_of_expr(expr).object()); |
112 | | - return check_renaming_l1(index_expr.array()) || |
113 | | - check_renaming(index_expr.index()); |
114 | | - } |
115 | | - else if(expr.id()==ID_symbol) |
116 | | - { |
117 | | - const auto &type = expr.type(); |
118 | | - if(!expr.get_bool(ID_C_SSA_symbol)) |
119 | | - return type.id() != ID_code && type.id() != ID_mathematical_function; |
120 | | - if(to_ssa_expr(expr).get_level_2().empty()) |
121 | | - return true; |
122 | | - if(to_ssa_expr(expr).get_original_expr().type() != type) |
123 | | - return true; |
124 | | - } |
125 | | - else |
126 | | - { |
127 | | - forall_operands(it, expr) |
128 | | - if(check_renaming(*it)) |
129 | | - return true; |
130 | | - } |
131 | | - |
132 | | - return false; |
133 | | -} |
134 | | - |
135 | 52 | template <> |
136 | 53 | renamedt<ssa_exprt, L0> |
137 | 54 | goto_symex_statet::set_indices<L0>(ssa_exprt ssa_expr, const namespacet &ns) |
@@ -344,6 +261,73 @@ goto_symex_statet::rename(exprt expr, const namespacet &ns) |
344 | 261 | } |
345 | 262 | } |
346 | 263 |
|
| 264 | +exprt goto_symex_statet::l2_rename_rvalues(exprt lvalue, const namespacet &ns) |
| 265 | +{ |
| 266 | + rename(lvalue.type(), irep_idt(), ns); |
| 267 | + |
| 268 | + if(lvalue.id() == ID_symbol) |
| 269 | + { |
| 270 | + // Nothing to do |
| 271 | + } |
| 272 | + else if(is_read_only_object(lvalue)) |
| 273 | + { |
| 274 | + // Ignore apparent writes to 'NULL-object' and similar read-only objects |
| 275 | + } |
| 276 | + else if(lvalue.id() == ID_typecast) |
| 277 | + { |
| 278 | + auto &typecast_lvalue = to_typecast_expr(lvalue); |
| 279 | + typecast_lvalue.op() = l2_rename_rvalues(typecast_lvalue.op(), ns); |
| 280 | + } |
| 281 | + else if(lvalue.id() == ID_member) |
| 282 | + { |
| 283 | + auto &member_lvalue = to_member_expr(lvalue); |
| 284 | + member_lvalue.compound() = l2_rename_rvalues(member_lvalue.compound(), ns); |
| 285 | + } |
| 286 | + else if(lvalue.id() == ID_index) |
| 287 | + { |
| 288 | + // The index is an rvalue: |
| 289 | + auto &index_lvalue = to_index_expr(lvalue); |
| 290 | + index_lvalue.array() = l2_rename_rvalues(index_lvalue.array(), ns); |
| 291 | + index_lvalue.index() = rename(index_lvalue.index(), ns).get(); |
| 292 | + } |
| 293 | + else if( |
| 294 | + lvalue.id() == ID_byte_extract_little_endian || |
| 295 | + lvalue.id() == ID_byte_extract_big_endian) |
| 296 | + { |
| 297 | + // The offset is an rvalue: |
| 298 | + auto &byte_extract_lvalue = to_byte_extract_expr(lvalue); |
| 299 | + byte_extract_lvalue.op() = l2_rename_rvalues(byte_extract_lvalue.op(), ns); |
| 300 | + byte_extract_lvalue.offset() = rename(byte_extract_lvalue.offset(), ns); |
| 301 | + } |
| 302 | + else if(lvalue.id() == ID_if) |
| 303 | + { |
| 304 | + // The condition is an rvalue: |
| 305 | + auto &if_lvalue = to_if_expr(lvalue); |
| 306 | + if_lvalue.cond() = rename(if_lvalue.cond(), ns); |
| 307 | + if(!if_lvalue.cond().is_false()) |
| 308 | + if_lvalue.true_case() = l2_rename_rvalues(if_lvalue.true_case(), ns); |
| 309 | + if(!if_lvalue.cond().is_true()) |
| 310 | + if_lvalue.false_case() = l2_rename_rvalues(if_lvalue.false_case(), ns); |
| 311 | + } |
| 312 | + else if(lvalue.id() == ID_complex_real) |
| 313 | + { |
| 314 | + auto &complex_real_lvalue = to_complex_real_expr(lvalue); |
| 315 | + complex_real_lvalue.op() = l2_rename_rvalues(complex_real_lvalue.op(), ns); |
| 316 | + } |
| 317 | + else if(lvalue.id() == ID_complex_imag) |
| 318 | + { |
| 319 | + auto &complex_imag_lvalue = to_complex_imag_expr(lvalue); |
| 320 | + complex_imag_lvalue.op() = l2_rename_rvalues(complex_imag_lvalue.op(), ns); |
| 321 | + } |
| 322 | + else |
| 323 | + { |
| 324 | + throw unsupported_operation_exceptiont( |
| 325 | + "l2_rename_rvalues case `" + lvalue.id_string() + "' not handled"); |
| 326 | + } |
| 327 | + |
| 328 | + return lvalue; |
| 329 | +} |
| 330 | + |
347 | 331 | template renamedt<exprt, L1> |
348 | 332 | goto_symex_statet::rename<L1>(exprt expr, const namespacet &ns); |
349 | 333 |
|
|
0 commit comments