@@ -369,6 +369,20 @@ void goto_symext::dereference_rec(exprt &expr, statet &state, bool write)
369
369
}
370
370
}
371
371
372
+ static exprt apply_to_objects_in_dereference (
373
+ exprt e, const std::function<exprt(exprt)> &f)
374
+ {
375
+ if (auto deref = expr_try_dynamic_cast<dereference_exprt>(e))
376
+ {
377
+ deref->op () = f (std::move (deref->op ()));
378
+ return *deref;
379
+ }
380
+
381
+ for (auto &sub : e.operands ())
382
+ sub = apply_to_objects_in_dereference (std::move (sub), f);
383
+ return e;
384
+ }
385
+
372
386
// / Replace all dereference operations within \p expr with explicit references
373
387
// / to the objects they may refer to. For example, the expression `*p1 + *p2`
374
388
// / might be rewritten to `obj1 + (p2 == &obj2 ? obj2 : obj3)` in the case where
@@ -408,19 +422,20 @@ void goto_symext::dereference_rec(exprt &expr, statet &state, bool write)
408
422
// / See \ref auto_objects.cpp for details.
409
423
void goto_symext::dereference (exprt &expr, statet &state, bool write)
410
424
{
411
- // The expression needs to be renamed to level 1
412
- // in order to distinguish addresses of local variables
413
- // from different frames. Would be enough to rename
414
- // symbols whose address is taken.
415
425
PRECONDITION (!state.call_stack ().empty ());
416
- exprt l1_expr = state.field_sensitivity .apply (
417
- ns, state, state.rename <L1>(expr, ns).get (), write );
426
+
427
+ // Symbols whose address is taken need to be renamed to level 1
428
+ // in order to distinguish addresses of local variables
429
+ // from different frames.
430
+ expr = apply_to_objects_in_dereference (std::move (expr), [&](exprt e) {
431
+ return state.field_sensitivity .apply (
432
+ ns, state, state.rename <L1>(std::move (e), ns).get (), false );});
418
433
419
434
// start the recursion!
420
- dereference_rec (l1_expr , state, write );
435
+ dereference_rec (expr , state, write );
421
436
// dereferencing may introduce new symbol_exprt
422
437
// (like __CPROVER_memory)
423
- expr = state.rename <L1>(std::move (l1_expr ), ns).get ();
438
+ expr = state.rename <L1>(std::move (expr ), ns).get ();
424
439
425
440
// Dereferencing is likely to introduce new member-of-if constructs --
426
441
// for example, "x->field" may have become "(x == &o1 ? o1 : o2).field."
0 commit comments