Skip to content

Commit f2f2c60

Browse files
Daniel Kroeningtautschnig
Daniel Kroening
authored andcommitted
Improve precision of value_set on unions by extending and using the simplifier
Previously, only the case of struct members with offset zero was handled with sufficient precision. Using structs inside unions where a member of non-zero offset is accessed is now handled precisely.
1 parent e1f5644 commit f2f2c60

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

regression/cbmc/union11/union_list.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <assert.h>
2+
3+
struct list_item
4+
{
5+
// there could be more members here, this single one suffices to demonstrate
6+
// the problem/fix
7+
struct list_item *previous;
8+
};
9+
10+
struct List
11+
{
12+
// an element such that the offset of "index" is non-zero
13+
unsigned something;
14+
struct list_item *index;
15+
struct list_item end;
16+
};
17+
18+
union U
19+
{
20+
// there could be more members here, this single one suffices to demonstrate
21+
// the problem/fix
22+
struct List my_list;
23+
};
24+
25+
int main()
26+
{
27+
union U u;
28+
29+
u.my_list.index = &(u.my_list.end);
30+
u.my_list.end.previous = u.my_list.index;
31+
struct list_item *p1 = u.my_list.index;
32+
struct list_item *p2 = p1->previous;
33+
struct list_item *p3 = p2->previous;
34+
assert(p3 != 0); // should pass
35+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
union_list.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/pointer-analysis/value_set.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ void value_sett::assign(
12041204

12051205
rhs_member=make_member(rhs, name, ns);
12061206

1207-
assign(lhs_member, rhs_member, ns, is_simplified, add_to_sets);
1207+
assign(lhs_member, rhs_member, ns, false, add_to_sets);
12081208
}
12091209
}
12101210
}

src/util/simplify_expr_struct.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,25 @@ bool simplify_exprt::simplify_member(exprt &expr)
172172

173173
return false;
174174
}
175+
else if(op_type.id() == ID_union)
176+
{
177+
// rewrite byte_extract(X, 0).member to X
178+
// if the type of X is that of the member
179+
const auto &byte_extract_expr = to_byte_extract_expr(op);
180+
if(byte_extract_expr.offset().is_zero())
181+
{
182+
const union_typet &union_type = to_union_type(op_type);
183+
const typet &subtype = union_type.component_type(component_name);
184+
185+
if(subtype == byte_extract_expr.op().type())
186+
{
187+
exprt tmp = byte_extract_expr.op();
188+
expr.swap(tmp);
189+
190+
return false;
191+
}
192+
}
193+
}
175194
}
176195
else if(op.id()==ID_union && op_type.id()==ID_union)
177196
{

0 commit comments

Comments
 (0)