If a small piece of C++ code is compiled with "-O2 -frename-registers", instead of "-O", the resulting executable will not work correct.
Created attachment 4603 [details] single C++ source file, ii file and g++ -v -save-temps output
I noticed this wrong behaviour since version 3.3. In version 3.2.1, it seems to be ok.
I can confirm this on the mainline but I think you are violating aliasing rules (confirmed but also using -fno-strict-alasing and running the program).
I'm not sure that this is really an aliasing problem. The only casts that happen in the program involve char*s. I'd like an aliasing expert to look at this first. W.
I tried using "-O3 -fno-strict-aliasing" and it seems to be ok, now. Is this the solution, or is there any more.
Here's a reduced testcase. It returns 1 when compiled with "g++ -O2" and 0 when compiled with "g++ -O2 -fno-strict-aliasing": ================================================ char Pool[32]; struct A { A* next; }; A* a=0; struct B { void* p; B() : p((void*)4711) {} void* operator new(unsigned) { if (!a) a = (A*)Pool; A* q = a; a = a->next; return q; } }; int main () { new B; return a == (void*)4711; } ================================================ I'm not sure whether this example violates aliasing rules, but it's an aliasing problem nevertheless. I updated the summary accordingly.
This looks like an almost exact dup of bug 11973. From that bug: Your code is invalid. What you do is this: - in new a->X_alc() you call C::operator new, which returns a C* which you later access - however, C::operator new calls alc(), which returns the memory location of an object which the compiler assumes is of type SList Such type games violate C++'s type aliasing rules. The solution is either to fix your code, or if you want to play hide-and-seek with the compiler, use -fno-strict-aliasing. The names of the functions are different but the game is the same. *** This bug has been marked as a duplicate of 11973 ***
I'd like to reopen this bug report again, for the same reason as before: here we are only dealing with char*, which is special. We still need to have someone with more knowledge of aliasing rules here. W.
Simple situation: If function is not inlined it works correct. If function is inlined it swaps 2 operations across this function and the calling one (operator new). Inlining should NEVER change net result in such cases. What's wrong with this code exactly ? Yuri (yuri@tsoft.com)
Not a bug. The provided testcase violate alias rules. The compiler assume that the two pointers, 'this' and 'a' in this->p = 4711 (inside constructor) and a = a->next (inside new operator) point to different object, which is not true in your code.
*** Bug 14822 has been marked as a duplicate of this bug. ***
Confirmed again to be invalid. What happens here is that the underlying char[] is accessed first through a A* (within operator new) and later through a B* (in B's constructor). This is equivalent to: float foo(void) { char buf[64]; int* p1 = (int*)buf; float* p2 = (float*)buf; *p1 = 123; return *p2; } This code breaks aliasing rules (confirmed by Segher Boessenkool and Paul Brook), so the whole PR is invalid.
*** Bug 15295 has been marked as a duplicate of this bug. ***
Reopening to ...
Mark as a dup of bug 21920. *** This bug has been marked as a duplicate of 21920 ***