A program which causes the warning: warning: dereferencing type-punned pointer will break strict-aliasing rules leads to incorrect code. Put this code in typepun.c: --------------------------------------- typedef unsigned short ushort; typedef unsigned long ulong; typedef struct { ushort field1; ushort field2; } twoshorts; void bug (ulong *p, int pcount) { twoshorts two; if (pcount == 1) { two.field2 = 0x400; two.field1 = 0x8300; *p = *(ulong *)&two; } } ------------------<end of typepun.c>--------------- and compile it with this script: mips64-elf-gcc -S -nostdinc -mips3 -mabi=32 -O2 -Wall typepun.c Examining the code, we see that two ushorts are written to a local struct, and then the whole struct is copied elsewhere as a ulong. (Yeah, it's gross, but in its defence, the original program that I cut down contains the keyword "volatile".) Examining the resulting .s file, we see (as 4 consecutive lines): sh $2,2($sp) lw $2,0($sp) li $3,-32000 sh $3,0($sp)
The above got committed before I was finished. Sigh. What's right about these four lines is that they store two halfwords (with "sh") and load a word (with "lw"). What's wrong is that they do it in the order {store,load,store}, not {store,store,load}. So the result (the returned word) contains 16 uninitialized bits from the stack frame. That's not OK. The latest 3.4 snapshot has this behavior. I believe 3.3 has the same problem: at least, it did in December.
The warning is correct, you are violating C89 (and C99 and C++) aliasing rules. Use an union to get around this problem (note C89 says this still is undefined but GCC defines this as what you are expecting).
It the compiler is about to generate incorrect code, then it shouldn't be a warning, it should be an error.
Subject: Re: type-punned pointer causes bad code On Sat, 27 Mar 2004, lindsayd at cisco dot com wrote: > It the compiler is about to generate incorrect code, then it shouldn't be a > warning, it should be an error. No, the function might never be executed. DR#109 is clear: "A conforming implementation must not fail to translate a strictly conforming program simply because _some_ possible execution of that program would result in undefined behavior.". http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_109.html
First, no, it shouldn't, since the code might never be actually executed at run time. Second, gcc cannot reliably detect this condition; it doesn't really know whether you actually dereference the type-punned pointer (if you don't, the code is OK).
The maybe the warning should be more sternly worded. While we're having this discussion, any idea why GCC-2.95.3 reliably generated working code for this construct, without issuing a warning?
Yes because the warning was not in 2.95.3 and -fstrict-aliasing was not enabled by default in 2.95.3 (but it was for 2.95 and people complained so we turned it off until 3.0 when we turned it back on).
JSM, what about rewording the message to make it clearer? Something like: "derefering type-punned pointer will break strict-aliasing rules, and might generate invalid code" or something like that. An explicit reference to the wrong-code problem might help.
Subject: Re: type-punned pointer causes bad code On Sun, 28 Mar 2004, giovannibajo at libero dot it wrote: > JSM, what about rewording the message to make it clearer? Something > like: "derefering type-punned pointer will break strict-aliasing rules, and > might generate invalid code" or something like that. An explicit reference to > the wrong-code problem might help. We could do with a proper index to the diagnostics. But for now adding an inform () with a suitable message following the warning would make sense.
The documentation of -Wstrict-aliasing references -fstrict-aliasing which states what exactly is wrong here. However, if someone is interested in cleaning something up: the last paragraph of the docs of -fstrict-aliasing should really go into the internals manual, not invoke.texi: -------------- Every language that wishes to perform language-specific alias analysis should define a function that computes, given an @code{tree} node, an alias set for the node. Nodes in different alias sets are not allowed to alias. For an example, see the C front-end function @code{c_get_alias_set}. --------------
Reopning to ...
Mark as a dup of bug 21920. *** This bug has been marked as a duplicate of 21920 ***