Skip to content

Commit b55f2c4

Browse files
Only apply field_sensitivity to dereferenced object
This is important to consider dereferenced object as read value.
1 parent 490ca60 commit b55f2c4

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/goto-symex/symex_dereference.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,20 @@ void goto_symext::dereference_rec(exprt &expr, statet &state, bool write)
368368
}
369369
}
370370

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+
371385
/// Replace all dereference operations within \p expr with explicit references
372386
/// to the objects they may refer to. For example, the expression `*p1 + *p2`
373387
/// 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)
407421
/// See \ref auto_objects.cpp for details.
408422
void goto_symext::dereference(exprt &expr, statet &state, bool write)
409423
{
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.
414424
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+
});
417433

418434
// start the recursion!
419-
dereference_rec(l1_expr, state, write);
435+
dereference_rec(expr, state, write);
420436
// dereferencing may introduce new symbol_exprt
421437
// (like __CPROVER_memory)
422-
expr = state.rename<L1>(std::move(l1_expr), ns).get();
438+
expr = state.rename<L1>(std::move(expr), ns).get();
423439

424440
// Dereferencing is likely to introduce new member-of-if constructs --
425441
// for example, "x->field" may have become "(x == &o1 ? o1 : o2).field."

0 commit comments

Comments
 (0)