Skip to content

Commit 3cc70b1

Browse files
committed
Union regression test of unspecified behaviour
The C standard leaves the values of bytes not belonging to the object representation of the member last stored unspecified, but GCC, Clang, and Visual Studio all seem to behave just as CBMC currently does. Ensure we maintain this behaviour via a regression test.
1 parent 67b36f0 commit 3cc70b1

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

regression/cbmc/union15/main.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <assert.h>
2+
3+
struct S
4+
{
5+
union U {
6+
int x;
7+
int y;
8+
} u;
9+
int z;
10+
} s = {1, 2};
11+
12+
union B {
13+
unsigned char b : 1;
14+
unsigned char c;
15+
};
16+
17+
union C {
18+
char c;
19+
int i;
20+
};
21+
22+
union A {
23+
struct
24+
{
25+
char c;
26+
char p[3];
27+
};
28+
int i;
29+
} x = {1};
30+
31+
int main()
32+
{
33+
// Make sure elements of initializer lists are assigned to the right members
34+
// (in particular, `2` is not to be assigned to the second component of the
35+
// union, but has to be assigned to the second member of the struct).
36+
assert(s.u.x == 1);
37+
assert(s.z == 2);
38+
assert(x.p[0] == 0);
39+
40+
// The C standard (6.2.6.1 (7)) states: "When a value is stored in a member of
41+
// an object of union type, the bytes of the object representation that do not
42+
// correspond to that member but do correspond to other members take
43+
// unspecified values." Appendix J.1 Unspecified behavior refers back to this:
44+
// "When a value is stored in a member of an object of union type, the bytes
45+
// of the object representation that do not correspond to that member but do
46+
// correspond to other members take unspecified values."
47+
//
48+
// GCC, Clang, Visual Studio (and possibly others) choose to maintain the
49+
// values of any bits not being assigned to. This includes bit fields, as the
50+
// following examples demonstrate.
51+
union B ub = {.c = 0xFF};
52+
ub.b = 0;
53+
assert(ub.c == 0xFE);
54+
55+
union C uc = {.i = 0xFFFFFFFF};
56+
uc.c = 0;
57+
assert(uc.i == 0xFFFFFF00);
58+
59+
union A ua = {.i = 0xFFFFFFFF};
60+
ua.c = 0;
61+
assert(ua.i == 0xFFFFFF00);
62+
}

regression/cbmc/union15/test.desc

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

0 commit comments

Comments
 (0)