@@ -364,6 +364,50 @@ 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
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
+
391
+ for (std::size_t i = 0 ; i < components.size (); ++i)
392
+ {
393
+ const auto &comp = components[i];
394
+ exprt lhs_field = member_exprt (lhs, comp.get_name (), comp.type ());
395
+ state.field_sensitivity .apply (ns, state, lhs_field, true );
396
+ INVARIANT (
397
+ lhs_field.id () == ID_symbol,
398
+ " member of symbol should be susceptible to field-sensitivity" );
399
+
400
+ const exprt &rhs_field = rhs.operands ()[i];
401
+ symex_assign_symbol (
402
+ state,
403
+ to_ssa_expr (lhs_field),
404
+ full_lhs,
405
+ rhs_field,
406
+ guard,
407
+ assignment_type);
408
+ }
409
+ }
410
+
367
411
void goto_symext::symex_assign_symbol (
368
412
statet &state,
369
413
const ssa_exprt &lhs, // L1
@@ -372,6 +416,14 @@ void goto_symext::symex_assign_symbol(
372
416
exprt::operandst &guard,
373
417
assignment_typet assignment_type)
374
418
{
419
+ // Shortcut the common case of a whole-struct initializer:
420
+ if (rhs.id () == ID_struct)
421
+ {
422
+ symex_assign_from_struct (
423
+ state, lhs, full_lhs, to_struct_expr (rhs), guard, assignment_type);
424
+ return ;
425
+ }
426
+
375
427
exprt ssa_rhs=rhs;
376
428
377
429
// put assignment guard into the rhs
0 commit comments