Skip to content

Commit db3ebcb

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 41e1403 commit db3ebcb

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
@@ -623,6 +623,52 @@ void goto_symex_statet::rename_address(
623623
}
624624
}
625625

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

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

0 commit comments

Comments
 (0)