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