Bug 47712

Summary: optimization (-O) of code using union unexpectedly causes essential code to be optimized away
Product: gcc Reporter: Simon Hardy-Francis <simonhf>
Component: rtl-optimizationAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: simonhf
Priority: P3    
Version: 4.5.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Simon Hardy-Francis 2011-02-12 18:19:33 UTC
Reproduce with:

mingw32-gcc.exe -DWITH_UNNECESSARY_CODE    example.c -oexample.exe && example.exe
mingw32-gcc.exe                            example.c -oexample.exe && example.exe
mingw32-gcc.exe -DWITH_UNNECESSARY_CODE -O example.c -oexample.exe && example.exe
mingw32-gcc.exe                         -O example.c -oexample.exe && example.exe

Shows output:

C:\20110211-gcc-bug>mingw32-gcc.exe -DWITH_UNNECESSARY_CODE    example.c -oexample.exe   && example.exe
before  copy_bytes(): source     : abcd
before  copy_bytes(): destination: 1234
calling copy_bytes(): copy source to destination
after   copy_bytes(): source     : abcd
after   copy_bytes(): destination: abcd <-- expected

C:\20110211-gcc-bug>mingw32-gcc.exe                            example.c -oexample.exe   && example.exe
before  copy_bytes(): source     : abcd
before  copy_bytes(): destination: 1234
calling copy_bytes(): copy source to destination
after   copy_bytes(): source     : abcd
after   copy_bytes(): destination: abcd <-- expected

C:\20110211-gcc-bug>mingw32-gcc.exe -DWITH_UNNECESSARY_CODE -O example.c -oexample.exe   && example.exe
before  copy_bytes(): source     : abcd
before  copy_bytes(): destination: 1234
calling copy_bytes(): copy source to destination
after   copy_bytes(): source     : abcd
after   copy_bytes(): destination: abcd <-- expected

C:\20110211-gcc-bug>mingw32-gcc.exe                         -O example.c -oexample.exe   && example.exe
before  copy_bytes(): source     : abcd
before  copy_bytes(): destination: 1234
calling copy_bytes(): copy source to destination
after   copy_bytes(): source     : abcd
after   copy_bytes(): destination: 1234 <-- not expected: the bug in action

example.c:

#include <stdio.h>
#include <stdlib.h>

typedef union PTR_UNION
{
    char * as_s08_ptr;
    unsigned int as_u32;
} PTR_UNION;

void copy_bytes(unsigned int address_as_u32, char * source, unsigned int size)
{
    unsigned int i;
    PTR_UNION destination;

    destination.as_u32 = address_as_u32;

    for (i=0 ; i<size; i++)
    {
        destination.as_s08_ptr[i] = source[i];
    }
#ifdef WITH_UNNECESSARY_CODE
    if ((size >= 1) && (destination.as_s08_ptr[0] != source[0])) {
        exit(1);
    }
#endif
}

void main(void)
{
    PTR_UNION address;
    char source[] = "abcd";
    char destination[] = "1234";

    printf("before  copy_bytes(): source     : %s\n", source);
    printf("before  copy_bytes(): destination: %s\n", destination);

    printf("calling copy_bytes(): copy source to destination\n");
    address.as_s08_ptr = destination;
    copy_bytes(address.as_u32, source, sizeof(source));

    printf("after   copy_bytes(): source     : %s\n", source);
    printf("after   copy_bytes(): destination: %s <-- %s\n", destination, strcmp(source, destination) ? "not expected: the bug in action" : "expected");
}

Workaround:

If you find this bug but want to continue compiling your code with the -O command line option then there are several workarounds:
1. Don't use the union :-)
2. Add the unnecessary code shown above.
Comment 1 Richard Biener 2011-02-13 10:15:57 UTC
Should be fixed in 4.5.2.

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