Skip to content

Union regression test of unspecified behaviour #5704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions regression/cbmc/union15/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <assert.h>

struct S
{
union U {
int x;
int y;
} u;
int z;
} s = {1, 2};

union B {
unsigned char b : 1;
unsigned char c;
};

union C {
char c;
int i;
};

union A {
struct
{
char c;
char p[3];
};
int i;
} x = {1};

int main()
{
// Make sure elements of initializer lists are assigned to the right members
// (in particular, `2` is not to be assigned to the second component of the
// union, but has to be assigned to the second member of the struct).
assert(s.u.x == 1);
assert(s.z == 2);
assert(x.p[0] == 0);

// The C standard (6.2.6.1 (7)) states: "When a value is stored in a member of
// an object of union type, the bytes of the object representation that do not
// correspond to that member but do correspond to other members take
// unspecified values." Appendix J.1 Unspecified behavior refers back to this:
// "When a value is stored in a member of an object of union type, the bytes
// of the object representation that do not correspond to that member but do
// correspond to other members take unspecified values."
//
// GCC, Clang, Visual Studio (and possibly others) choose to maintain the
// values of any bits not being assigned to. This includes bit fields, as the
// following examples demonstrate.
union B ub = {.c = 0xFF};
ub.b = 0;
assert(ub.c == 0xFE);

union C uc = {.i = 0xFFFFFFFF};
uc.c = 0;
assert(uc.i == 0xFFFFFF00);

union A ua = {.i = 0xFFFFFFFF};
ua.c = 0;
assert(ua.i == 0xFFFFFF00);
}
8 changes: 8 additions & 0 deletions regression/cbmc/union15/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE broken-smt-backend
main.c

^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
^warning: ignoring