http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47712

           Summary: optimization (-O) of code using union unexpectedly
                    causes essential code to be optimized away
           Product: gcc
           Version: 4.5.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: simo...@gmail.com


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.

Reply via email to