This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Marking C++ new operator as malloc?


Hi,

On Sat, Sep 08, 2007 at 10:16:41PM +0200, Basile STARYNKEVITCH wrote:
> Chris Lattner wrote:
>> I understand, but allowing users to override new means that the actual 
>> implementation may not honor the aliasing guarantees of attribute malloc.
>> -Chris
>
> Maybe it could make sense to give the malloc attribute only to ::operator 
> new but not to other new-s, in particular not to the placement new?
>
> But I am not a C++ expert!

Neither am I. However, I have  done a small series of experiments that
showed  this is  exactly what  happens with  the patch  I sent  in the
original mail.

Obviously,  this thread  is not  about placement  new which  I believe
definitely cannot have the flag set.

I compiled four small tests  with both patched and untampered compiler
(revision 128277) and compared dumps. The exact dumps and some further
details are  attached, here  I'll just list  three of the  sources and
briefly summarize the effect of the patch.

1. Allocating a simple int (in fact the same example as in PR23383):

    int f(void)
    {
      int t;
      int *a = new int;
      int *b = new int;
      *a = 1;
      *b = 2;
      t = *a;
      delete a;
      delete b;
      return t;
    }

  The patched compiler turnes return into "return 1" and removes the
  load to t. The unpatched does neither.

2. Allocating a simple class:

    class A 
    {
    public:
      int d;
    };
    
    int f(void)
    {
      int t;
      A *a = new A;
      A *b = new A;
      a->d = 1;
      b->d = 2;
      t = a->d;
      delete a;
      delete b;
      return t;
    }
    
  The same thing. Patched version returns 1, original performs load.

3. Allocating a simple class with a redefined new operator.

    class A 
    {
    public:
      int d;
      static void* operator new (size_t size); 
      static void operator delete (void *p);
    };
    
    static A pool[2];
    static int n = 0;
    
    __attribute__ ((noinline)) void* A::operator new (size_t size)
    {
      // the following should be dangerous enough:
      void *p = &pool[n];
      n++;
      return p; 
    }
    
    __attribute__ ((noinline)) void A::operator delete (void *p)
    {	
      // no-op
    } 
    
    int f(void)
    {
      int t;
      A *a = new A;
      A *b = new A;
      a->d = 1;
      b->d = 2;
      t = a->d;
      delete a;
      delete b;
      return t;
    }
     
  Both patched  and original compiler produced exactly  the same dump,
  the patched version did not perform any (unsafe) transformations.

So my conclusion is that redefined new operators are not an issue and
the attribute does not affect them. 

Martin

Attachment: new.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]