@@ -223,6 +223,26 @@ void goto_symext::dereference_rec(exprt &expr, statet &state, bool write)
223223 // first make sure there are no dereferences in there
224224 dereference_rec (tmp1, state, false );
225225
226+ // Depending on the nature of the pointer expression, the recursive deref
227+ // operation might have introduced a construct such as
228+ // (x == &o1 ? o1 : o2).field, in which case we should simplify to push the
229+ // member operator inside the if, then apply field-sensitivity to yield
230+ // (x == &o1 ? o1..field : o2..field). value_set_dereferencet can then
231+ // apply the dereference operation to each of o1..field and o2..field
232+ // independently, as it special-cases the ternary conditional operator.
233+ do_simplify (tmp1);
234+
235+ if (symex_config.run_validation_checks )
236+ {
237+ // make sure simplify has not re-introduced any dereferencing that
238+ // had previously been cleaned away
239+ INVARIANT (
240+ !has_subexpr (tmp1, ID_dereference),
241+ " simplify re-introduced dereferencing" );
242+ }
243+
244+ tmp1 = state.field_sensitivity .apply (ns, state, std::move (tmp1), write);
245+
226246 // we need to set up some elaborate call-backs
227247 symex_dereference_statet symex_dereference_state (state, ns);
228248
@@ -241,10 +261,6 @@ void goto_symext::dereference_rec(exprt &expr, statet &state, bool write)
241261
242262 // this may yield a new auto-object
243263 trigger_auto_object (expr, state);
244-
245- // ...and may have introduced a member-of-symbol construct with a
246- // corresponding SSA symbol:
247- expr = state.field_sensitivity .apply (ns, state, std::move (expr), write);
248264 }
249265 else if (
250266 expr.id () == ID_index && to_index_expr (expr).array ().id () == ID_member &&
0 commit comments