Skip to content

Commit 175dfa8

Browse files
committed
Temporarily restore limited type renaming
1 parent db9e4f3 commit 175dfa8

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

regression/cbmc/vla1/main.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <assert.h>
2+
3+
int main(int argc, char *argv[])
4+
{
5+
unsigned char x = argc;
6+
// make sure int multiplication below won't overflow - type casting to
7+
// unsigned long long would be possible, but puts yields a challenging problem
8+
// for the SAT solver
9+
__CPROVER_assume(x < 1ULL << (sizeof(int) * 8 / 2 - 1));
10+
11+
struct S
12+
{
13+
int a;
14+
int b[x];
15+
int c;
16+
};
17+
18+
if(x % 2 == 0)
19+
x = 3;
20+
21+
struct S s[x];
22+
23+
__CPROVER_assume(x < 255);
24+
++x;
25+
26+
assert(sizeof(struct S) == ((unsigned char)argc + 2) * sizeof(int));
27+
assert(sizeof(s) == (x - 1) * ((unsigned char)argc + 2) * sizeof(int));
28+
29+
return 0;
30+
}

regression/cbmc/vla1/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/goto-symex/goto_symex_state.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,12 +613,70 @@ void goto_symex_statet::rename_address(
613613
}
614614
}
615615

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+
616669
void goto_symex_statet::rename(
617670
typet &type,
618671
const irep_idt &l1_identifier,
619672
const namespacet &ns,
620673
levelt level)
621674
{
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+
622680
// rename all the symbols with their last known value
623681
// to the given level
624682

0 commit comments

Comments
 (0)