Skip to content

Commit 7d6cb94

Browse files
authored
Merge pull request #5704 from tautschnig/union-test-2
Union regression test of unspecified behaviour
2 parents 6f2d284 + 3cc70b1 commit 7d6cb94

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)