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?


Joe Buck wrote:

>> In the case of "malloc", and assuming that all of the machinery for
>> malloc is hidden away in some piece of the program we're not talking
>> about, all three definitions apply.  Each pointer returned by malloc is
>> an island unto itself; there's no conforming way to get there except by
>> using the pointer just returned.
> 
> The key point is that the mechanism is hidden away.  This might become
> more of an issue with LTO, so the question is how to make such guarantees
> make sense to an optimizer that can see the full program.

Correct.  The "malloc" attribute is only applicable to "malloc" because
we can't see how "malloc" is implemented.

>> This seems like a useful optimization to me, and I understand that it
>> will work 99.99% of the time, and it's in the spirit of the standard --
>> but how do we actually make it safe?  If the attribute only applied to
>> other values returned from the same function, then it would be safe --
>> but less useful.  Can we do better?
> 
> Maybe "pool", if exported, would have to be marked as aliasing the "new"
> calls, possibly with some new attribute "malloc_implementation" or
> something like that. 

It's worse than that:

  char *pool;
  void set_pool(char *p) { pool = p; }
  void *operator new(size_t s) { // return stuff from pool. }

  bool f() {
     char *p = new char[1024];
     set_pool (p);
     char *i = new char;
     return (p == i);
  }

In other words, pointers from any part of the program can potentially be
"laundered" through set_pool and return via the new operator.  I don't
see any way to make this fully safe, in general, without the limitation
I imposed: the no-aliasing guarantee only applies to the values returned
from the function called.

For a particular implementation of "operator new" (such as the one in
libstdc++), you can of course make it safe in the same way as "malloc";
hide the implementation somewhere the rest of the program can't see it
(modulo LTO).  But, to declare it with the "malloc" attribute in the
headers seems dangerous, since we have no way of knowing if the user
replaced it, off in some file somewhere we don't know about, but in such
a way that pointers in our source code are being laundered back to us.

Perhaps we could have an <ext/i_promise_i_will_not_define_new> header,
which you can include if you aren't overriding the operator...

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713


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