@@ -218,15 +218,21 @@ struct assignmentt final
218
218
// / place.
219
219
// / \param [in, out] state: symbolic execution state to perform renaming
220
220
// / \param assignment: an assignment to rewrite
221
+ // / \param full_lhs: expression skeleton corresponding to \p lhs as it should
222
+ // / appear in the result trace
221
223
// / \param ns: namespace
222
- // / \return the updated assignment
223
- static assignmentt rewrite_with_to_field_symbols (
224
+ // / \return the updated assignment and the corresponding updated version of
225
+ // / \p full_lhs
226
+ static std::pair<assignmentt, exprt> rewrite_with_to_field_symbols (
224
227
goto_symext::statet &state,
225
228
assignmentt assignment,
229
+ const exprt &full_lhs,
226
230
const namespacet &ns)
227
231
{
228
232
exprt &ssa_rhs = assignment.rhs ;
229
233
ssa_exprt &lhs_mod = assignment.lhs ;
234
+ exprt updated_full_lhs = full_lhs;
235
+
230
236
#ifdef USE_UPDATE
231
237
while (ssa_rhs.id () == ID_update &&
232
238
to_update_expr (ssa_rhs).designator ().size () == 1 &&
@@ -288,9 +294,33 @@ static assignmentt rewrite_with_to_field_symbols(
288
294
289
295
ssa_rhs = with_expr.new_value ();
290
296
lhs_mod = to_ssa_expr (field_sensitive_lhs);
297
+
298
+ std::reference_wrapper<const exprt> full_lhs_ref = full_lhs;
299
+ while (full_lhs_ref.get ().id () == ID_typecast)
300
+ full_lhs_ref = to_typecast_expr (full_lhs_ref.get ()).op ();
301
+ const exprt &full_lhs_without_typecast = full_lhs_ref.get ();
302
+ if (full_lhs_without_typecast.id () == ID_index)
303
+ {
304
+ updated_full_lhs =
305
+ to_index_expr (full_lhs_without_typecast).array ();
306
+ }
307
+ else if (full_lhs_without_typecast.id () == ID_member)
308
+ {
309
+ updated_full_lhs =
310
+ to_member_expr (full_lhs_without_typecast).compound ();
311
+ }
312
+ else
313
+ {
314
+ INVARIANT (
315
+ full_lhs_without_typecast.id () == ID_byte_extract_little_endian
316
+ || full_lhs_without_typecast.id () == ID_byte_extract_big_endian,
317
+ " full_lhs in with assignment should be index, member or byte_extract" );
318
+ updated_full_lhs =
319
+ to_byte_extract_expr (full_lhs_without_typecast).operands ()[0 ];
320
+ }
291
321
}
292
322
#endif
293
- return assignment;
323
+ return { assignment, updated_full_lhs} ;
294
324
}
295
325
296
326
// / Replace byte-update operations that only affect individual fields of an
@@ -455,7 +485,9 @@ void goto_symext::symex_assign_symbol(
455
485
// in the future these should be omitted.
456
486
auto assignment = shift_indexed_access_to_lhs (
457
487
state, assignmentt{lhs, std::move (l2_rhs)}, ns, symex_config.simplify_opt );
458
- assignment = rewrite_with_to_field_symbols (state, std::move (assignment), ns);
488
+ exprt updated_full_lhs;
489
+ std::tie (assignment, updated_full_lhs) = rewrite_with_to_field_symbols (
490
+ state, std::move (assignment), full_lhs, ns);
459
491
460
492
do_simplify (assignment.rhs );
461
493
@@ -470,7 +502,7 @@ void goto_symext::symex_assign_symbol(
470
502
symex_config.allow_pointer_unsoundness )
471
503
.get ();
472
504
473
- exprt ssa_full_lhs = add_to_lhs (full_lhs , l2_lhs);
505
+ exprt ssa_full_lhs = add_to_lhs (updated_full_lhs , l2_lhs);
474
506
state.record_events .push (false );
475
507
const exprt l2_full_lhs = state.rename (std::move (ssa_full_lhs), ns).get ();
476
508
state.record_events .pop ();
0 commit comments