Skip to content

Commit fbd06ba

Browse files
committed
Create SSA-level 2 names for individual fields
During symex, a declaration introduces non-deterministic values for the declared symbol by creating a fresh L2 name without assigning any value to it. With field-sensitive SSA, the same must be done for each field (just like we already did the inverse for objects going out of scope via a DEAD instruction).
1 parent 6c8954b commit fbd06ba

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

regression/cbmc/struct14/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
struct S
2+
{
3+
int x;
4+
};
5+
6+
int main(int argc, char *argv[])
7+
{
8+
struct S s;
9+
10+
if(argc > 3)
11+
s.x = 42;
12+
13+
__CPROVER_assert(s.x == 42, "should fail");
14+
}

regression/cbmc/struct14/test.desc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
^warning: ignoring
9+
--
10+
With field-sensitive SSA encoding we need to make sure that each struct member
11+
is treated as non-deterministic unless initialised.

src/goto-symex/symex_decl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
6767
std::size_t generation = state.increase_generation(l1_identifier, ssa);
6868
CHECK_RETURN(generation == 1);
6969

70+
const exprt fields = state.field_sensitivity.get_fields(ns, state, ssa);
71+
if(fields != ssa)
72+
{
73+
std::set<symbol_exprt> fields_set;
74+
find_symbols(fields, fields_set);
75+
76+
for(const auto &l1_symbol : fields_set)
77+
{
78+
ssa_exprt field_ssa = to_ssa_expr(l1_symbol);
79+
std::size_t field_generation =
80+
state.increase_generation(l1_symbol.get_identifier(), field_ssa);
81+
CHECK_RETURN(field_generation == 1);
82+
}
83+
}
84+
7085
const bool record_events=state.record_events;
7186
state.record_events=false;
7287
exprt expr_l2 = state.rename(std::move(ssa), ns).get();

0 commit comments

Comments
 (0)