Skip to content

Commit 15ca388

Browse files
Synchronize full_lhs/lhs in rewrite_with_to_field_symbols
If lhs_mod is modified, full_lhs needs to be modified in the same way to keep the coherent. Otherwise the trace could end-up with meaningless assignments.
1 parent c945ec0 commit 15ca388

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

src/goto-symex/symex_assign.cpp

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,21 @@ struct assignmentt final
218218
/// place.
219219
/// \param [in, out] state: symbolic execution state to perform renaming
220220
/// \param assignment: an assignment to rewrite
221+
/// \param full_lhs: expression skeleton corresponding to \p lhs as it should
222+
/// appear in the result trace
221223
/// \param ns: namespace
222-
/// \return the updated assignment
223-
static assignmentt rewrite_with_to_field_symbols(
224+
/// \return the updated assignment and the corresponding updated version of
225+
/// \p full_lhs
226+
static std::pair<assignmentt, exprt> rewrite_with_to_field_symbols(
224227
goto_symext::statet &state,
225228
assignmentt assignment,
229+
const exprt &full_lhs,
226230
const namespacet &ns)
227231
{
228232
exprt &ssa_rhs = assignment.rhs;
229233
ssa_exprt &lhs_mod = assignment.lhs;
234+
exprt updated_full_lhs = full_lhs;
235+
230236
#ifdef USE_UPDATE
231237
while(ssa_rhs.id() == ID_update &&
232238
to_update_expr(ssa_rhs).designator().size() == 1 &&
@@ -288,9 +294,33 @@ static assignmentt rewrite_with_to_field_symbols(
288294

289295
ssa_rhs = with_expr.new_value();
290296
lhs_mod = to_ssa_expr(field_sensitive_lhs);
297+
298+
std::reference_wrapper<const exprt> full_lhs_ref = full_lhs;
299+
while(full_lhs_ref.get().id() == ID_typecast)
300+
full_lhs_ref = to_typecast_expr(full_lhs_ref.get()).op();
301+
const exprt &full_lhs_without_typecast = full_lhs_ref.get();
302+
if(full_lhs_without_typecast.id() == ID_index)
303+
{
304+
updated_full_lhs =
305+
to_index_expr(full_lhs_without_typecast).array();
306+
}
307+
else if(full_lhs_without_typecast.id() == ID_member)
308+
{
309+
updated_full_lhs =
310+
to_member_expr(full_lhs_without_typecast).compound();
311+
}
312+
else
313+
{
314+
INVARIANT(
315+
full_lhs_without_typecast.id() == ID_byte_extract_little_endian
316+
|| full_lhs_without_typecast.id() == ID_byte_extract_big_endian,
317+
"full_lhs in with assignment should be index, member or byte_extract");
318+
updated_full_lhs =
319+
to_byte_extract_expr(full_lhs_without_typecast).operands()[0];
320+
}
291321
}
292322
#endif
293-
return assignment;
323+
return {assignment, updated_full_lhs};
294324
}
295325

296326
/// Replace byte-update operations that only affect individual fields of an
@@ -455,7 +485,9 @@ void goto_symext::symex_assign_symbol(
455485
// in the future these should be omitted.
456486
auto assignment = shift_indexed_access_to_lhs(
457487
state, assignmentt{lhs, std::move(l2_rhs)}, ns, symex_config.simplify_opt);
458-
assignment = rewrite_with_to_field_symbols(state, std::move(assignment), ns);
488+
exprt updated_full_lhs;
489+
std::tie(assignment, updated_full_lhs) = rewrite_with_to_field_symbols(
490+
state, std::move(assignment), full_lhs, ns);
459491

460492
do_simplify(assignment.rhs);
461493

@@ -470,7 +502,7 @@ void goto_symext::symex_assign_symbol(
470502
symex_config.allow_pointer_unsoundness)
471503
.get();
472504

473-
exprt ssa_full_lhs = add_to_lhs(full_lhs, l2_lhs);
505+
exprt ssa_full_lhs = add_to_lhs(updated_full_lhs, l2_lhs);
474506
state.record_events.push(false);
475507
const exprt l2_full_lhs = state.rename(std::move(ssa_full_lhs), ns).get();
476508
state.record_events.pop();

0 commit comments

Comments
 (0)