[Bug c/65892] gcc fails to implement N685 aliasing of union members
myriachan at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Sep 9 00:39:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892
Melissa <myriachan at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |myriachan at gmail dot com
--- Comment #12 from Melissa <myriachan at gmail dot com> ---
This is broken in C++ as well, and in C++, the rules are much more clear that
GCC isn't following them.
Quoting the C++ Standard, revision 4296 (post-C++14?):
16. The "common initial sequence" of two standard-layout struct (Clause 9)
types is the longest sequence of non-static data members and bit-fields in
declaration order, starting with the first such entity in each of the structs,
such that the corresponding entries have layout-compatible types and either
neither entity is a bit-field or both are bit-fields with the same width.
19. In a standard-layout union with an active member (9.5) of struct type T1,
it is permitted to read a non-static data member m of another union member of
struct type T2 provided m is part of the common initial sequence of T1 and T2.
A C++ conversion of the original example is below. I asked about the word
"read" on the C++ Standard Discussion (std-discussion) mailing list, because it
probably should also allow writing if it allows reads. As a result, I modified
the below to only *read* in an aliasing way, to fully comply with the written
word of the Standard.
#include <cassert>
struct t1 { int m; };
struct t2 { int m; };
union U {
t1 s1;
t2 s2;
};
int f (t1 *p1, t2 *p2)
{
// union U visible here, p1->m and p2->m may alias
// p1 is the active member; read from p2 per [class.mem]/19.
if (p2->m < 0)
p1->m = -p1->m;
return p2->m;
}
int main (void)
{
union U u = { { -1 } };
int n = f (&u.s1, &u.s2);
assert (1 == n);
return 0;
}
More information about the Gcc-bugs
mailing list