Description of problem: gcc miscompiles the following snippet of code (from the attached interface.i file): if (object->idef) ipactive->flags |= 1 << 0; It renders it incorrectly as: je .L9 movl 28, %edx xorl %eax, %eax orl $1, %edx movl %edx, 28(%eax) .L9: Note the second instruction is wrong... it should be reading from memory location 28(%edi). Furthermore, if the for loop in the example is removed, then the following ASM is produced: orl $1,28 Which is also wrong. Version-Release number of selected component (if applicable): The bug occurs in the Phoebe-beta4 gcc: dhowells>gcc -v Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.1/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux Thread model: posix gcc version 3.2.1 20021207 (Red Hat Linux 8.0 3.2.1-2) And also the RH9 gcc: dhowells>gcc -v Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux Thread model: posix gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) How reproducible: 100%. Just compile the .i file as below Steps to Reproduce: 1. Compile the .i file with this command line: gcc -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -fomit-frame-pointer -nostdinc -iwithprefix include -S interface.i 2. Look at the resulting .s file. Actual results: The faulty code will lie near the end of the resulting assembly code, and will look something like: .L11: movl (%esi), %eax testl %eax, %eax je .L9 movl 28, %edx <---- xorl %eax, %eax orl $1, %edx movl %edx, 28(%eax) .L9: movl $-61, %eax .L1: popl %ebx popl %esi ret Additional info: See attached "interface.i" file.
Created attachment 91151 [details] testcase for showing problem
I've spotted the basic problem in my code. The code was, at that point, accessing a local variable that had been initialised to NULL and was not changed between the two points. However, the fact that the first access had the register reference removed (but the second access still had it) was confusing... perhaps a warning should be generated?
There has been a proposal for warning about dereferencing NULL. http://gcc.gnu.org/PR16351 Whether it makes it in or not is another question.