@@ -67,11 +67,13 @@ void goto_symext::process_array_expr_rec(
6767 expr.swap (tmp);
6868 }
6969 else
70+ {
7071 Forall_operands (it, expr)
7172 {
7273 typet t=it->type ();
7374 process_array_expr_rec (*it, t);
7475 }
76+ }
7577
7678 if (!base_type_eq (expr.type (), type, ns))
7779 {
@@ -166,12 +168,41 @@ void goto_symext::replace_array_equal(exprt &expr)
166168 replace_array_equal (*it);
167169}
168170
171+ // / Rewrite index/member expressions in byte_extract to offset
172+ static void adjust_byte_extract_rec (exprt &expr, const namespacet &ns)
173+ {
174+ Forall_operands (it, expr)
175+ adjust_byte_extract_rec (*it, ns);
176+
177+ if (expr.id ()==ID_byte_extract_big_endian ||
178+ expr.id ()==ID_byte_extract_little_endian)
179+ {
180+ byte_extract_exprt &be=to_byte_extract_expr (expr);
181+ if (be.op ().id ()==ID_symbol &&
182+ to_ssa_expr (be.op ()).get_original_expr ().get_bool (ID_C_invalid_object))
183+ return ;
184+
185+ object_descriptor_exprt ode;
186+ ode.build (expr, ns);
187+
188+ be.op ()=ode.root_object ();
189+ be.offset ()=ode.offset ();
190+ }
191+ }
192+
169193void goto_symext::clean_expr (
170194 exprt &expr,
171195 statet &state,
172196 const bool write)
173197{
174198 replace_nondet (expr);
175199 dereference (expr, state, write);
200+
201+ // make sure all remaining byte extract operations use the root
202+ // object to avoid nesting of with/update and byte_update when on
203+ // lhs
204+ if (write)
205+ adjust_byte_extract_rec (expr, ns);
206+
176207 replace_array_equal (expr);
177208}
0 commit comments