Here is the revised patch and additional test case. ~Aaron
On Wed, May 29, 2013 at 10:49 AM, Aaron Ballman <[email protected]> wrote: > #include <stdio.h> > #include <stdlib.h> > > struct arbitrary_t {} arbitrary; > > void *operator new[]( size_t s, arbitrary_t ) throw() { return ::malloc( s ); > } > > struct S { > void *operator new( size_t s, arbitrary_t ) throw() { return ::malloc( s ); > } > }; > > int main() { > S *s = new (arbitrary) S[2]; > } > > This will yield a call to the global operator new[] instead of the > class-specific operator new. Using new instead of new[] yields a call > to the matching class-specific operator new still. So I think my test > will have to move down below the check for a global operator new: > > <look for member operator new> > <look for global operator new> > +if (not found && looking for array new && MS mode) > + <switch to looking for non-array new> > + <look for global operator new> > > If you agree, then I'll make the changes and add another test to > CodeGenCXX to ensure we're calling the proper one. > > ~Aaron > > On Tue, May 28, 2013 at 9:00 PM, Richard Smith <[email protected]> wrote: >> OK, based on off-line discussion, it seems that MSVC doesn't use a placement >> operator delete *at all*. The approach in the patch of switching to using >> the non-array forms for both if we don't find 'operator new[]' makes sense >> to me. >> >> The patch doesn't look quite right, though. We have: >> >> <look for member operator new> >> +if (not found && looking for array new && MS mode) >> + <switch to looking for non-array new> >> + <look for global operator new> >> <look for global operator new> >> >> ... which will never use a global array new in MS mode, and will never use a >> class-specific non-array new for an array allocation. >> >> One more question, then. What happens if there's no class-specific 'operator >> new[]', but there is both a matching class-specific 'operator new' and a >> matching global 'operator new[]'? >> >> On Tue, May 28, 2013 at 5:04 PM, Richard Smith <[email protected]> >> wrote: >>> >>> On Tue, May 28, 2013 at 4:50 PM, Aaron Ballman <[email protected]> >>> wrote: >>>> >>>> On Tue, May 28, 2013 at 6:07 PM, Richard Smith <[email protected]> >>>> wrote: >>>> > What does MSVC think about: >>>> > >>>> > void *operator new(unsigned int size, arbitrary_t); >>>> > void operator delete[](unsigned int size, arbitrary_t) = delete; >>>> > struct S { S(); }; >>>> > S *p = new (arbitrary) S[5]; >>>> > >>>> > ? Will it call the (deleted) operator delete[] even though it picked a >>>> > non-array operator new? >>>> >>>> MSVC doesn't support deleted functions as of right now, so it just errors >>>> out. >>>> >>>> > What if there is an array new but no array delete? >>>> >>>> struct arbitrary_t {} arbitrary; >>>> void *operator new(unsigned int size, arbitrary_t); >>>> >>>> void f() { >>>> int *p = new(arbitrary) int[4]; >>>> int *p2 = new(arbitrary) int; >>>> >>>> delete [] p; >>>> delete p2; >>>> } >>>> >>>> Yields calls to: >>>> >>>> call ??3@YAXPAX@Z ; operator delete >>>> >>>> for both p and p2, so it falls back on the global delete. >>> >>> >>> I don't think that answers my question, though. What I'd like to know is, >>> should we fall back from operator delete[] to operator delete exactly when >>> we fall back from operator new[] to operator new (as your patch does), or >>> should we perform the two fallbacks independently? >> >>
operator_new.patch
Description: Binary data
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
