Skip to content

Commit 821da14

Browse files
committed
Remove requires_renaming
We return a renamed type if, and only if, renaming was necessary. Thus we can do the is-it-necessary and the actual renaming in a single pass.
1 parent 2d8ca77 commit 821da14

File tree

2 files changed

+8
-66
lines changed

2 files changed

+8
-66
lines changed

regression/cbmc/struct13/test.desc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33

44
^EXIT=0$
@@ -8,5 +8,4 @@ main.c
88
^warning: ignoring
99
--
1010
Just like pointers, array members may have subtypes of the same type as the
11-
containing struct. requires_renaming fails to catch this case, which results in
12-
unbounded recursion.
11+
containing struct.

src/goto-symex/goto_symex_state.cpp

Lines changed: 6 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -632,54 +632,6 @@ void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
632632
}
633633
}
634634

635-
/// Return true if, and only if, the \p type or one of its subtypes requires SSA
636-
/// renaming. Renaming is necessary when symbol expressions occur within the
637-
/// type, which is the case for arrays of non-constant size.
638-
static bool requires_renaming(const typet &type, const namespacet &ns)
639-
{
640-
if(type.id() == ID_array)
641-
{
642-
const auto &array_type = to_array_type(type);
643-
return requires_renaming(array_type.subtype(), ns) ||
644-
!array_type.size().is_constant();
645-
}
646-
else if(
647-
type.id() == ID_struct || type.id() == ID_union || type.id() == ID_class)
648-
{
649-
const struct_union_typet &s_u_type = to_struct_union_type(type);
650-
const struct_union_typet::componentst &components = s_u_type.components();
651-
652-
for(auto &component : components)
653-
{
654-
// be careful, or it might get cyclic
655-
if(
656-
component.type().id() != ID_pointer &&
657-
requires_renaming(component.type(), ns))
658-
{
659-
return true;
660-
}
661-
}
662-
663-
return false;
664-
}
665-
else if(type.id() == ID_pointer)
666-
{
667-
return requires_renaming(to_pointer_type(type).subtype(), ns);
668-
}
669-
else if(type.id() == ID_union_tag)
670-
{
671-
const symbolt &symbol = ns.lookup(to_union_tag_type(type));
672-
return requires_renaming(symbol.type, ns);
673-
}
674-
else if(type.id() == ID_struct_tag)
675-
{
676-
const symbolt &symbol = ns.lookup(to_struct_tag_type(type));
677-
return requires_renaming(symbol.type, ns);
678-
}
679-
680-
return false;
681-
}
682-
683635
template <levelt level>
684636
void goto_symex_statet::rename(
685637
typet &type,
@@ -704,32 +656,26 @@ optionalt<typet> goto_symex_statet::rename_type(
704656
const irep_idt &l1_identifier,
705657
const namespacet &ns)
706658
{
707-
// check whether there are symbol expressions in the type; if not, there
708-
// is no need to expand the struct/union tags in the type
709-
if(!requires_renaming(type, ns))
710-
return {};
711-
712659
// rename all the symbols with their last known value
713660
// to the given level
714661

715-
std::pair<l1_typest::iterator, bool> l1_type_entry;
716662
if(level==L2 &&
717663
!l1_identifier.empty())
718664
{
719-
l1_type_entry=l1_types.insert(std::make_pair(l1_identifier, type));
665+
auto l1_type_entry = l1_types.find(l1_identifier);
720666

721-
if(!l1_type_entry.second) // was already in map
667+
if(l1_type_entry != l1_types.end())
722668
{
723669
// do not change a complete array type to an incomplete one
724670

725-
const typet &type_prev=l1_type_entry.first->second;
671+
const typet &type_prev = l1_type_entry->second;
726672

727673
if(type.id()!=ID_array ||
728674
type_prev.id()!=ID_array ||
729675
to_array_type(type).is_incomplete() ||
730676
to_array_type(type_prev).is_complete())
731677
{
732-
return l1_type_entry.first->second;
678+
return l1_type_entry->second;
733679
}
734680
}
735681
}
@@ -805,14 +751,11 @@ optionalt<typet> goto_symex_statet::rename_type(
805751
}
806752
else if(type.id() == ID_struct_tag || type.id() == ID_union_tag)
807753
{
808-
const typet &followed_type = ns.follow(type);
809-
result = rename_type<level>(followed_type, l1_identifier, ns);
810-
if(!result.has_value())
811-
result = followed_type;
754+
result = rename_type<level>(ns.follow(type), l1_identifier, ns);
812755
}
813756

814757
if(level == L2 && !l1_identifier.empty() && result.has_value())
815-
l1_type_entry.first->second = *result;
758+
l1_types.emplace(l1_identifier, *result);
816759

817760
return result;
818761
}

0 commit comments

Comments
 (0)