Skip to content

Commit 7032a1f

Browse files
committed
Support byte-extract lowering over union of non-constant size
The test included made apparent that we weren't yet handling unbounded byte extracts (out of a bounded object) for unions, which just fell back to unpacking an empty array.
1 parent b4a4122 commit 7032a1f

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

regression/cbmc/union17/main.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
int main()
2+
{
3+
// create a union type of non-constant, non-zero size
4+
unsigned x;
5+
__CPROVER_assume(x > 0);
6+
union U
7+
{
8+
unsigned A[x];
9+
};
10+
// create an integer of arbitrary value
11+
int i, i_before;
12+
i_before = i;
13+
// initialize a union of non-zero size from the integer
14+
unsigned u = ((union U *)&i)->A[0];
15+
// reading back an integer out of the union should yield the same value for
16+
// the integer as it had before
17+
i = u;
18+
__CPROVER_assert(i == i_before, "going through union works");
19+
}

regression/cbmc/union17/test.desc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE broken-smt-backend
2+
main.c
3+
--no-simplify
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
9+
--
10+
This test passes when simplification is enabled (which gets rid of
11+
byte-extracting a union of non-constant size), but yielded a wrong verification
12+
outcome with both the SAT back-end before. The SMT back-end fails for it would
13+
like to flatten an array of non-constant size.

src/solvers/lowering/byte_operators.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,18 @@ static exprt unpack_rec(
940940
ns,
941941
true);
942942
}
943+
else if(!union_type.components().empty())
944+
{
945+
member_exprt member{src, union_type.components().front()};
946+
return unpack_rec(
947+
member,
948+
little_endian,
949+
offset_bytes,
950+
max_bytes,
951+
bits_per_byte,
952+
ns,
953+
true);
954+
}
943955
}
944956
else if(src.type().id() == ID_pointer)
945957
{

0 commit comments

Comments
 (0)