[PATCH] Fallback to operator new for MSVC compatibility

Aaron Ballman aaron at aaronballman.com
Wed May 29 10:50:45 PDT 2013


Here is the revised patch and additional test case.

~Aaron

On Wed, May 29, 2013 at 10:49 AM, Aaron Ballman <aaron at aaronballman.com> 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 <richard at metafoo.co.uk> 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 <richard at metafoo.co.uk>
>> wrote:
>>>
>>> On Tue, May 28, 2013 at 4:50 PM, Aaron Ballman <aaron at aaronballman.com>
>>> wrote:
>>>>
>>>> On Tue, May 28, 2013 at 6:07 PM, Richard Smith <richard at metafoo.co.uk>
>>>> 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 at 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?
>>
>>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: operator_new.patch
Type: application/octet-stream
Size: 3417 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130529/8e600a62/attachment.obj>


More information about the cfe-commits mailing list