Skip to content

Commit bbd08bc

Browse files
authored
Merge pull request #5713 from tautschnig/value-set-union
Value sets must not be field sensitive for unions
2 parents 36fa6f4 + 1b73ae5 commit bbd08bc

File tree

4 files changed

+50
-11
lines changed

4 files changed

+50
-11
lines changed

regression/cbmc/union14/test.desc

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

44
^EXIT=0$
@@ -7,6 +7,5 @@ main.c
77
--
88
^warning: ignoring
99
--
10-
Value sets do not properly track pointers through byte-extract operations. Thus
11-
derferencing yields __CPROVER_memory, which results in a spurious verification
12-
failure.
10+
Value sets did not properly track pointers through unions. Thus derferencing
11+
yields __CPROVER_memory, which results in a spurious verification failure.

regression/cbmc/union16/main.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
typedef void (*callback_t)(void);
2+
3+
struct xfer
4+
{
5+
union { /*< FIX: union -> struct */
6+
struct
7+
{
8+
int *buf;
9+
callback_t callback; /*< FIX: remove */
10+
} a;
11+
};
12+
} g_xfer;
13+
14+
int g_buf;
15+
16+
int main()
17+
{
18+
g_xfer = (struct xfer){{{&g_buf}}};
19+
20+
/* FIX, uncomment (only on cbmc develop 9ee5b9d6): */
21+
// g_xfer.a.buf = &g_buf;
22+
23+
/* check the pointer was initialized properly */
24+
assert(g_xfer.a.buf == &g_buf);
25+
26+
g_xfer.a.buf[0] = 42; /* write a value via the pointer */
27+
assert(g_xfer.a.buf[0] == 42); /* check it was written */
28+
assert(g_buf == 42); /* the underlying value should also be updated */
29+
}

regression/cbmc/union16/test.desc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
9+
--
10+
Value sets did not properly track pointers through unions. This regression test
11+
was provided in #5263, including comments about simplifications that make it
12+
work.

src/pointer-analysis/value_set.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,10 +1180,9 @@ void value_sett::assign(
11801180

11811181
const typet &type=ns.follow(lhs.type());
11821182

1183-
if(type.id()==ID_struct ||
1184-
type.id()==ID_union)
1183+
if(type.id() == ID_struct)
11851184
{
1186-
for(const auto &c : to_struct_union_type(type).components())
1185+
for(const auto &c : to_struct_type(type).components())
11871186
{
11881187
const typet &subtype = c.type();
11891188
const irep_idt &name = c.get_name();
@@ -1212,10 +1211,10 @@ void value_sett::assign(
12121211
"rhs.type():\n" +
12131212
rhs.type().pretty() + "\n" + "lhs.type():\n" + lhs.type().pretty());
12141213

1215-
const struct_union_typet &rhs_struct_union_type =
1216-
to_struct_union_type(ns.follow(rhs.type()));
1214+
const struct_typet &rhs_struct_type =
1215+
to_struct_type(ns.follow(rhs.type()));
12171216

1218-
const typet &rhs_subtype = rhs_struct_union_type.component_type(name);
1217+
const typet &rhs_subtype = rhs_struct_type.component_type(name);
12191218
rhs_member = simplify_expr(member_exprt{rhs, name, rhs_subtype}, ns);
12201219

12211220
assign(lhs_member, rhs_member, ns, true, add_to_sets);
@@ -1284,7 +1283,7 @@ void value_sett::assign(
12841283
}
12851284
else
12861285
{
1287-
// basic type
1286+
// basic type or union
12881287
object_mapt values_rhs = get_value_set(rhs, ns, is_simplified);
12891288

12901289
// Permit custom subclass to alter the read values prior to write:

0 commit comments

Comments
 (0)