Bug 11915 - Aliasing problems with user-defined operator new
Summary: Aliasing problems with user-defined operator new
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3.1
: P2 normal
Target Milestone: 3.4.0
Assignee: Not yet assigned to anyone
Keywords: wrong-code
: 14822 15295 (view as bug list)
Depends on:
Reported: 2003-08-14 07:47 UTC by Andreas Glowatz
Modified: 2005-07-23 22:49 UTC (History)
3 users (show)

See Also:
Host: i686-linux-gnu
Target: i686-linux-gnu
Build: i686-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:

single C++ source file, ii file and g++ -v -save-temps output (94.04 KB, application/x-gzip)
2003-08-14 07:51 UTC, Andreas Glowatz

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Glowatz 2003-08-14 07:47:27 UTC
If a small piece of C++ code is compiled with "-O2 -frename-registers", instead of
"-O", the resulting executable will not work correct.
Comment 1 Andreas Glowatz 2003-08-14 07:51:54 UTC
Created attachment 4603 [details]
single C++ source file, ii file and g++ -v -save-temps output
Comment 2 Andreas Glowatz 2003-08-14 07:59:12 UTC
I noticed this wrong behaviour since version 3.3. In version 3.2.1, it seems to
be ok.
Comment 3 Andrew Pinski 2003-08-14 13:33:39 UTC
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).
Comment 4 Wolfgang Bangerth 2003-08-14 14:21:41 UTC
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. 
Comment 5 Andreas Glowatz 2003-08-14 14:29:36 UTC
I tried using "-O3 -fno-strict-aliasing" and it seems to be ok, now. Is this the
solution, or is there any more.
Comment 6 Volker Reichelt 2003-08-15 18:41:15 UTC
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.
Comment 7 Andrew Pinski 2003-08-18 22:48:24 UTC
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 ***
Comment 8 Wolfgang Bangerth 2003-08-18 23:18:54 UTC
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. 
Comment 9 Yuri 2003-08-19 00:46:06 UTC
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)
Comment 10 Kriang Lerdsuwanakij 2003-08-24 15:30:51 UTC
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)
  a = a->next  (inside new operator)
point to different object, which is not true in your code.
Comment 11 Andrew Pinski 2004-04-02 12:30:44 UTC
*** Bug 14822 has been marked as a duplicate of this bug. ***
Comment 12 Giovanni Bajo 2004-04-02 14:22:30 UTC
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.
Comment 13 Andrew Pinski 2004-05-05 12:41:29 UTC
*** Bug 15295 has been marked as a duplicate of this bug. ***
Comment 14 Andrew Pinski 2005-06-05 08:45:14 UTC
Reopening to ...
Comment 15 Andrew Pinski 2005-06-05 08:45:31 UTC
Mark as a dup of bug 21920.

*** This bug has been marked as a duplicate of 21920 ***