Skip to content

Commit 64c7d39

Browse files
author
Daniel Kroening
committed
goto_symex: rename type symbols only when needed
Renaming a type is rarely needed: this is necessary only if the type contains a struct that contains a variable-sized member, which is a gcc extension. The key benefit of not renaming in all other cases is that struct and union tag types no longer get expanded.
1 parent b2c5cf1 commit 64c7d39

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

src/goto-symex/goto_symex_state.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,52 @@ void goto_symex_statet::rename_address(
625625
}
626626
}
627627

628+
static bool requires_renaming(const typet &type, const namespacet &ns)
629+
{
630+
if(type.id() == ID_array)
631+
{
632+
const auto &array_type = to_array_type(type);
633+
return requires_renaming(array_type.subtype(), ns) ||
634+
!array_type.size().is_constant();
635+
}
636+
else if(
637+
type.id() == ID_struct || type.id() == ID_union || type.id() == ID_class)
638+
{
639+
const struct_union_typet &s_u_type = to_struct_union_type(type);
640+
const struct_union_typet::componentst &components = s_u_type.components();
641+
642+
for(auto &component : components)
643+
{
644+
// be careful, or it might get cyclic
645+
if(component.type().id() != ID_pointer)
646+
return requires_renaming(component.type(), ns);
647+
}
648+
649+
return false;
650+
}
651+
else if(type.id() == ID_pointer)
652+
{
653+
return requires_renaming(to_pointer_type(type).subtype(), ns);
654+
}
655+
else if(type.id() == ID_symbol_type)
656+
{
657+
const symbolt &symbol = ns.lookup(to_symbol_type(type));
658+
return requires_renaming(symbol.type, ns);
659+
}
660+
else if(type.id() == ID_union_tag)
661+
{
662+
const symbolt &symbol = ns.lookup(to_union_tag_type(type));
663+
return requires_renaming(symbol.type, ns);
664+
}
665+
else if(type.id() == ID_struct_tag)
666+
{
667+
const symbolt &symbol = ns.lookup(to_struct_tag_type(type));
668+
return requires_renaming(symbol.type, ns);
669+
}
670+
671+
return false;
672+
}
673+
628674
void goto_symex_statet::rename(
629675
typet &type,
630676
const irep_idt &l1_identifier,
@@ -633,7 +679,6 @@ void goto_symex_statet::rename(
633679
{
634680
// rename all the symbols with their last known value
635681
// to the given level
636-
637682
std::pair<l1_typest::iterator, bool> l1_type_entry;
638683
if(level==L2 &&
639684
!l1_identifier.empty())
@@ -657,6 +702,11 @@ void goto_symex_statet::rename(
657702
}
658703
}
659704

705+
// check whether there are symbol expressions in the type; if not, there
706+
// is no need to expand the struct/union tags in the type
707+
if(!requires_renaming(type, ns))
708+
return; // no action
709+
660710
if(type.id()==ID_array)
661711
{
662712
auto &array_type = to_array_type(type);

0 commit comments

Comments
 (0)