@@ -613,12 +613,70 @@ void goto_symex_statet::rename_address(
613
613
}
614
614
}
615
615
616
+ // / Return true if, and only if, the \p type or one of its subtypes requires SSA
617
+ // / renaming. Renaming is necessary when symbol expressions occur within the
618
+ // / type, which is the case for arrays of non-constant size.
619
+ static bool requires_renaming (const typet &type, const namespacet &ns)
620
+ {
621
+ if (type.id () == ID_array)
622
+ {
623
+ const auto &array_type = to_array_type (type);
624
+ return requires_renaming (array_type.subtype (), ns) ||
625
+ !array_type.size ().is_constant ();
626
+ }
627
+ else if (
628
+ type.id () == ID_struct || type.id () == ID_union || type.id () == ID_class)
629
+ {
630
+ const struct_union_typet &s_u_type = to_struct_union_type (type);
631
+ const struct_union_typet::componentst &components = s_u_type.components ();
632
+
633
+ for (auto &component : components)
634
+ {
635
+ // be careful, or it might get cyclic
636
+ if (
637
+ component.type ().id () != ID_pointer &&
638
+ requires_renaming (component.type (), ns))
639
+ {
640
+ return true ;
641
+ }
642
+ }
643
+
644
+ return false ;
645
+ }
646
+ else if (type.id () == ID_pointer)
647
+ {
648
+ return requires_renaming (to_pointer_type (type).subtype (), ns);
649
+ }
650
+ else if (type.id () == ID_symbol_type)
651
+ {
652
+ const symbolt &symbol = ns.lookup (to_symbol_type (type));
653
+ return requires_renaming (symbol.type , ns);
654
+ }
655
+ else if (type.id () == ID_union_tag)
656
+ {
657
+ const symbolt &symbol = ns.lookup (to_union_tag_type (type));
658
+ return requires_renaming (symbol.type , ns);
659
+ }
660
+ else if (type.id () == ID_struct_tag)
661
+ {
662
+ const symbolt &symbol = ns.lookup (to_struct_tag_type (type));
663
+ return requires_renaming (symbol.type , ns);
664
+ }
665
+
666
+ return false ;
667
+ }
668
+
616
669
void goto_symex_statet::rename (
617
670
typet &type,
618
671
const irep_idt &l1_identifier,
619
672
const namespacet &ns,
620
673
levelt level)
621
674
{
675
+ // check whether there are symbol expressions in the type; if not, there
676
+ // is no need to expand the struct/union tags in the type
677
+ if (!requires_renaming (type, ns))
678
+ return ; // no action
679
+
622
680
// rename all the symbols with their last known value
623
681
// to the given level
624
682
0 commit comments