@@ -369,6 +369,20 @@ void goto_symext::dereference_rec(exprt &expr, statet &state, bool write)
369369 }
370370}
371371
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+
372386// / Replace all dereference operations within \p expr with explicit references
373387// / to the objects they may refer to. For example, the expression `*p1 + *p2`
374388// / 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)
408422// / See \ref auto_objects.cpp for details.
409423void goto_symext::dereference (exprt &expr, statet &state, bool write)
410424{
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.
415425 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 );});
418433
419434 // start the recursion!
420- dereference_rec (l1_expr , state, write);
435+ dereference_rec (expr , state, write);
421436 // dereferencing may introduce new symbol_exprt
422437 // (like __CPROVER_memory)
423- expr = state.rename <L1>(std::move (l1_expr ), ns).get ();
438+ expr = state.rename <L1>(std::move (expr ), ns).get ();
424439
425440 // Dereferencing is likely to introduce new member-of-if constructs --
426441 // for example, "x->field" may have become "(x == &o1 ? o1 : o2).field."
0 commit comments