Skip to content

Commit fe4a59d

Browse files
Only apply field_sensitivity to dereferenced object
This is important to consider dereferenced object as read value.
1 parent 09bff09 commit fe4a59d

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

src/goto-symex/symex_dereference.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
409423
void 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

Comments
 (0)