@@ -364,6 +364,51 @@ static void shift_indexed_access_to_lhs(
364
364
}
365
365
}
366
366
367
+ // / Assign a struct expression to a symbol. If \ref symex_assign_symbol was used
368
+ // / then we would assign the whole symbol, before extracting its components,
369
+ // / with results like `x = {1, 2}; x..field1 = x.field1; x..field2 = x.field2;`
370
+ // / This abbreviates the process, directly producing
371
+ // / `x..field1 = 1; x..field2 = 2;`
372
+ // / \param state: goto-symex state
373
+ // / \param lhs: symbol to assign (already renamed to L1)
374
+ // / \param full_lhs: expression skeleton corresponding to \p lhs, to be included
375
+ // / in the result trace
376
+ // / \param rhs: struct expression to assign to \p lhs
377
+ // / \param guard: guard conjuncts that must hold for this assignment to be made
378
+ // / \param assignment_type: assignment type (see
379
+ // / \ref symex_targett::assignment_typet)
380
+ void goto_symext::symex_assign_from_struct (
381
+ statet &state,
382
+ const ssa_exprt &lhs, // L1
383
+ const exprt &full_lhs,
384
+ const struct_exprt &rhs,
385
+ exprt::operandst &guard,
386
+ assignment_typet assignment_type)
387
+ {
388
+ const struct_typet &type = to_struct_type (ns.follow (lhs.type ()));
389
+ const struct_union_typet::componentst &components = type.components ();
390
+ PRECONDITION (rhs.operands ().size () == components.size ());
391
+
392
+ for (std::size_t i = 0 ; i < components.size (); ++i)
393
+ {
394
+ const auto &comp = components[i];
395
+ exprt lhs_field = member_exprt (lhs, comp.get_name (), comp.type ());
396
+ state.field_sensitivity .apply (ns, state, lhs_field, true );
397
+ INVARIANT (
398
+ lhs_field.id () == ID_symbol,
399
+ " member of symbol should be susceptible to field-sensitivity" );
400
+
401
+ const exprt &rhs_field = rhs.operands ()[i];
402
+ symex_assign_symbol (
403
+ state,
404
+ to_ssa_expr (lhs_field),
405
+ full_lhs,
406
+ rhs_field,
407
+ guard,
408
+ assignment_type);
409
+ }
410
+ }
411
+
367
412
void goto_symext::symex_assign_symbol (
368
413
statet &state,
369
414
const ssa_exprt &lhs, // L1
@@ -372,6 +417,14 @@ void goto_symext::symex_assign_symbol(
372
417
exprt::operandst &guard,
373
418
assignment_typet assignment_type)
374
419
{
420
+ // Shortcut the common case of a whole-struct initializer:
421
+ if (rhs.id () == ID_struct)
422
+ {
423
+ symex_assign_from_struct (
424
+ state, lhs, full_lhs, to_struct_expr (rhs), guard, assignment_type);
425
+ return ;
426
+ }
427
+
375
428
exprt ssa_rhs=rhs;
376
429
377
430
// put assignment guard into the rhs
0 commit comments