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.