With gcc-snapshot (Debian 20091118-1) 4.5.0 20091119 (experimental) [trunk revision 154312] on an x86_64 GNU/Linux machine and the following code (partly based on GMP): #include <stdio.h> union ieee_double_extract { struct { unsigned int manl:32; unsigned int manh:20; unsigned int exp:11; unsigned int sig:1; } s; double d; }; int main (void) { union { double d; unsigned long long i; } x; x.d = 0.0 / 0.0; printf ("d = %g [%llx]\n", x.d, x.i); printf ("exp = %x\n", (unsigned int) ((union ieee_double_extract *)&(x.d))->s.exp); return 0; } $ gcc-snapshot -Wall -Wextra testd.c -o testd $ ./testd d = nan [fff8000000000000] exp = 7ff This is OK, but with -O2: $ gcc-snapshot -Wall -Wextra testd.c -o testd -O2 $ ./testd d = nan [fff8000000000000] exp = 0 I don't know whether aliasing rules are broken, but note that there are no warnings. GCC 4.4.2 doesn't have this problem.
Aliasing rules are indeed broken because you access a union of anonymous type through a pointer to a union of type ieee_double_extract. I think you want union { union ieee_double_extract d; unsigned long long i; } x; x.d.d = 0.0 / 0.0; printf ("d = %g [%llx]\n", x.d.d, x.d.i); printf ("exp = %x\n", (unsigned int) x.d.s.exp); return 0; or even simplified.
> note that there are no warnings A warning is issued with -Wstrict-aliasing=1 or -Wstrict-aliasing=2, but no warning with -Wstrict-aliasing=3 (or -Wall). I see there are already a few bug reports about this.
Correct. We can either produce possibly lots of false positives or not warn. Warning in the cases where we can prove your code is wrong would be pointless as in that case we'd better take measures to not miscompile it (and we then can do so as we were able to detect the situation). With 4.4 one alias warning machinery did exactly this (warn but then not miscompile - but then it didn't warn in cases where it _did_ miscompile). It's generally impossible to please all folks here ;)
(In reply to comment #1) > Aliasing rules are indeed broken because you access a union of anonymous type > through a pointer to a union of type ieee_double_extract. OK, the real code in MPFR is a "double" accessed through a pointer to a union of type ieee_double_extract, but I suppose this is the same problem. BTW, could my testcase be used to improve GCC's -Wstrict-aliasing=3 (i.e. to have fewer false negatives without introducing more false positives), or is it too difficult / not possible?
The frontend code should indeed be able to unconditionally warn for ((union ieee_double_extract *)&(x.d))->s.exp because it can see both the underlying object and the access through the non-conflicting type.