https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63729

            Bug ID: 63729
           Summary: Type-punning through a union fails to circumvent
                    strict aliasing under certain conditions.
           Product: gcc
           Version: 4.9.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mednafen at gmail dot com

Linux x86_64, gcc 4.9.2

Bad:
$ gcc -Wall -O2 -o pun pun.c
$ ./pun 
0x00000005

Good:
$ gcc -Wall -fno-strict-aliasing -O2 -o pun pun.c
$ ./pun 
0x00000001

//
//
//

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;

typedef union
{
 uint16 data16[256];
 uint32 data32[128];
} zu;

uint32 __attribute__((noinline,noclone)) test(uint32 offset)
{
 zu z;

 *(uint32*)(((uint8*)z.data32) + offset) = 4;
 *(uint16*)(((uint8*)z.data16) + offset) = 0;
 *(uint32*)(((uint8*)z.data32) + offset) = *(uint32*)(((uint8*)z.data32) +
offset) + 1;

 return *(uint32*)(((uint8*)z.data32) + offset);
}

int main()
{
 __builtin_printf("0x%08x\n", test(0));
 return 0;
}

Reply via email to