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