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.<div>
<br></div><div>The patch doesn't look quite right, though. We have:</div><div><br></div><div> <look for member operator new></div><div>+if (not found && looking for array new && MS mode)</div><div>
+  <switch to looking for non-array new></div><div>+  <look for global operator new></div><div> <look for global operator new></div><div><br></div><div>... 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.</div>
<div><br></div><div>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[]'?</div>
<div><br><div class="gmail_quote">On Tue, May 28, 2013 at 5:04 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Tue, May 28, 2013 at 4:50 PM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br></div></div><div class="gmail_quote">
<div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>On Tue, May 28, 2013 at 6:07 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> 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>
</div>MSVC doesn't support deleted functions as of right now, so it just errors out.<br>
<div><br>
> What if there is an array new but no array delete?<br>
<br>
</div><div>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>
</div>  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.</blockquote><div><br></div></div></div><div>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?</div>

</div>
</blockquote></div><br></div>