I believe to have found a C++ program for which optimized (-O2) compilation on an i686 machine by combination of function inlining and out-of-order instruction scheduling leads to assembler code in which two registers point to the same piece of memory in two different roles, and accesses to it are performed in the wrong order, leading to a crash in the code. I couldn't find an earlier bug report subsuming my problem. I tried but failed to construct a small example; apparently the problem depends on a large context. I have attached a single preprocessed source file resched_aliasing.ii (1.2 MB) which was created by $ g++-3.3.3 -Wno-deprecated -O2 -Wall -g -c resched_aliasing.C -E -o resched_aliasing.ii -I(many dirs) -D(some defines) The errorneous assembler output resched_aliasing.s can be generated with $ g++-3.3.3 -O2 resched_aliasing.ii -g -S (I've left out the .s file according to the bug reporting instructions.) Both invocations of g++ do not generate warnings etc. The executable created from that code (which requires linking against several libraries that are irrelevant here) crashes with a SIGSEGV in the following place (see .s file after label .LBB1256 in line 7695): ( 1) .LBB1256: ( 2) movl _ZN4CORE10MemoryPoolINS_9BigRatRepEE7memPoolE, %eax ( 3) testl %eax, %eax ( 4) jne .L2368 (jump is taken) ( 5) ... ( 6) .L2368: ( 7) decl _ZN4CORE10MemoryPoolINS_9BigRatRepEE7memPoolE+4 ( 8) movl %eax, %ebx ( 9) movl -40(%ebp), %edi (10) movl $1, (%ebx) (11) movl (%eax), %eax This code is a mixture of a MemoryPool, maintaining a linked list of uninitialized or destroyed BigRatRep objects, and the constructor of BigRatRep's base class RCRepImpl, which initializes the refCount member varible at offset 0 to the value 1. The relevant source code lines are these: (.ii file, around line 34719) template<class T> class MemoryPool { // ... void* allocate(size_t) { if (next == __null) expandFreeList(); MemoryPool<T> *head = next; next = head->next; nCount --; return head; } // ... }; (.ii file, around line 36991) template<class Deriving> class RCRepImpl { public: RCRepImpl() : refCount(1) {} // ... }; In line (2) of the assembler code, the pointer `next' is read into %eax. It is then checked to be non-zero (lines (3..6)). The decrement of `nCount' in line (7) and the unrelated line (9) are irrelevant here. The problem is that in (8) %ebx becomes an alias for %eax, and the initialization of refCount to 1 in line (9) is scheduled before `next = head->next' takes place in line (11): now (11) is an access to the illegal address 0x1, causing the segfault. The problem goes away when compiling without optimization or when making the allocate() member function non-inline (by giving its definition outside the class definition). The incriminated pieces of source code come from the current beta snapshot of the CORE library. Other parts of the source code come from gmp-4.1.3 and boost-1.30.2 and the yet unreleased EXACUS library project. Their various open source licenses apply. I'm using g++-3.3.3 which was configured as follows: ./configure --prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3 --enable-languages=c,c++ : (reconfigured) ./configure --prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3 --enable-languages=c,c++ : (reconfigured) ./configure --prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3 --enable-languages=c,c++ Thanks a lot in advance!
Created attachment 6225 [details] Test case mentioned in report
This is a dup of either bug 11915, 14822 or many other invalid aliasing "bugs". *** This bug has been marked as a duplicate of 11915 ***