Bug 14750 - type-punned pointer causes bad code
Summary: type-punned pointer causes bad code
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-03-27 03:58 UTC by lindsayd
Modified: 2005-07-23 22:49 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: mips64-unknown-elf
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description lindsayd 2004-03-27 03:58:07 UTC
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)
Comment 1 lindsayd 2004-03-27 04:09:38 UTC
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.
Comment 2 Andrew Pinski 2004-03-27 08:40:02 UTC
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).
Comment 3 lindsayd 2004-03-27 19:44:10 UTC
It the compiler is about to generate incorrect code, then it shouldn't be a
warning, it should be an error.
Comment 4 Joseph S. Myers 2004-03-27 19:52:41 UTC
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

Comment 5 Falk Hueffner 2004-03-27 19:52:46 UTC
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).
Comment 6 lindsayd 2004-03-27 20:19:58 UTC
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?
Comment 7 Andrew Pinski 2004-03-27 20:23:01 UTC
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).
Comment 8 Giovanni Bajo 2004-03-28 03:09:38 UTC
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.
Comment 9 Joseph S. Myers 2004-03-28 13:02:00 UTC
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.

Comment 10 Wolfgang Bangerth 2004-03-29 04:54:56 UTC
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}. 
-------------- 
Comment 11 Andrew Pinski 2005-06-05 08:42:38 UTC
Reopning to ...
Comment 12 Andrew Pinski 2005-06-05 08:42:52 UTC
Mark as a dup of bug 21920.

*** This bug has been marked as a duplicate of 21920 ***