Skip to content

Commit abd6508

Browse files
Daniel Kroeningtautschnig
Daniel Kroening
authored andcommitted
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 df4b417 commit abd6508

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

src/goto-symex/goto_symex_state.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,12 +618,63 @@ void goto_symex_statet::rename_address(
618618
}
619619
}
620620

621+
static bool requires_renaming(const typet &type, const namespacet &ns)
622+
{
623+
if(type.id() == ID_array)
624+
{
625+
const auto &array_type = to_array_type(type);
626+
return requires_renaming(array_type.subtype(), ns) ||
627+
!array_type.size().is_constant();
628+
}
629+
else if(
630+
type.id() == ID_struct || type.id() == ID_union || type.id() == ID_class)
631+
{
632+
const struct_union_typet &s_u_type = to_struct_union_type(type);
633+
const struct_union_typet::componentst &components = s_u_type.components();
634+
635+
for(auto &component : components)
636+
{
637+
// be careful, or it might get cyclic
638+
if(component.type().id() != ID_pointer)
639+
return requires_renaming(component.type(), ns);
640+
}
641+
642+
return false;
643+
}
644+
else if(type.id() == ID_pointer)
645+
{
646+
return requires_renaming(to_pointer_type(type).subtype(), ns);
647+
}
648+
else if(type.id() == ID_symbol_type)
649+
{
650+
const symbolt &symbol = ns.lookup(to_symbol_type(type));
651+
return requires_renaming(symbol.type, ns);
652+
}
653+
else if(type.id() == ID_union_tag)
654+
{
655+
const symbolt &symbol = ns.lookup(to_union_tag_type(type));
656+
return requires_renaming(symbol.type, ns);
657+
}
658+
else if(type.id() == ID_struct_tag)
659+
{
660+
const symbolt &symbol = ns.lookup(to_struct_tag_type(type));
661+
return requires_renaming(symbol.type, ns);
662+
}
663+
664+
return false;
665+
}
666+
621667
void goto_symex_statet::rename(
622668
typet &type,
623669
const irep_idt &l1_identifier,
624670
const namespacet &ns,
625671
levelt level)
626672
{
673+
// check whether there are symbol expressions in the type; if not, there
674+
// is no need to expand the struct/union tags in the type
675+
if(!requires_renaming(type, ns))
676+
return; // no action
677+
627678
// rename all the symbols with their last known value
628679
// to the given level
629680

0 commit comments

Comments
 (0)