[cfe-dev] Why the argument of `delete' is converted to void* ?
Jean-Daniel Dupas
devlists at shadowlab.org
Wed Jul 4 08:07:34 PDT 2012
Le 4 juil. 2012 à 15:57, Enea Zaffanella a écrit :
> On 07/04/2012 03:35 PM, Jean-Daniel Dupas wrote:
>>
>> Le 4 juil. 2012 à 14:42, Abramo Bagnara a écrit :
>>
>>> Il 04/07/2012 14:01, Jean-Daniel Dupas ha scritto:
>>>>
>>>> Le 4 juil. 2012 à 12:42, Enea Zaffanella a écrit :
>>>>
>>>>> We have noticed that, in the AST produced by clang, the expression
>>>>> argument of a CXXDeleteExpr node is implicitly converted to void*:
>>>>>
>>>>> # cat delete.cc
>>>>> struct S {};
>>>>>
>>>>> void free(S* ps) {
>>>>> delete ps;
>>>>> }
>>>>>
>>>>> # llvm/Debug+Asserts/bin/clang -cc1 -ast-dump delete.cc
>>>>> [...]
>>>>> void free(S *ps) (CompoundStmt 0x4822650 <delete.cc:3:18, line:5:1>
>>>>> (CXXDeleteExpr 0x4822628 <line:4:3, col:10> 'void'
>>>>> (ImplicitCastExpr 0x4821df8 <col:10> 'void *' <BitCast>
>>>>> (ImplicitCastExpr 0x4821de0 <col:10> 'struct S *' <LValueToRValue>
>>>>> (DeclRefExpr 0x4821db8 <col:10> 'struct S *' lvalue ParmVar
>>>>> 0x47eeb20 'ps' 'struct S *')))))
>>>>>
>>>>>
>>>>> What are the reasons for introducing such an implicit cast?
>>>>>
>>>>> Enea.
>>>>
>>>> Just a though, but isn't it because the signature of delete is:
>>>>
>>>> operator delete(void *);
>>>
>>> I don't think so:
>>>
>>> delete ptr;
>>>
>>> is something very different from
>>>
>>> operator delete(ptr);
>>
>>
>> I'm not sure it is quite different.
>>
>> This is the IR generated by clang++ for this code with c++filt _ZdlPv =
>> operator delete(void*):
>>
>> define void @_Z4freeP1S(%struct.S* %ps) nounwind uwtable ssp {
>> entry:
>> %isnull = icmp eq %struct.S* %ps, null
>> br i1 %isnull, label %delete.end, label %delete.notnull
>>
>> delete.notnull: ; preds = %entry
>> %0 = getelementptr inbounds %struct.S* %ps, i64 0, i32 0
>> tail call void @_ZdlPv(i8* %0) nounwind
>> br label %delete.end
>>
>> delete.end: ; preds = %delete.notnull, %entry
>> ret void
>> }
>>
>> declare void @_ZdlPv(i8*) nounwind
>>
>>
>>
>>
>> -- Jean-Daniel
>
>
> Sorry for the misunderstanding, but the original question was not really meant to be restricted to classes having a trivial destructor (if you add a non-trivial destructor to class S then "delete ps" will call it, whereas "operator delete(ps)" will not).
>
> To rephrase my question: since in the general case "delete ps" may also call the destructor, why is its argument (always) converted to void*?
>
> Cheers,
> Enea.
AFAIK, even with a non trivial destructor, the code always end up calling the operator delete(void *) to free the memory.
It will generate something like this:
call the destructor on the struct.
call operator delete((void *)ps);
or in LLVM IR:
tail call void @_ZN1SD1Ev(%struct.S* %ps) nounwind // ps->~S()
%0 = getelementptr inbounds %struct.S* %ps, i64 0, i32 0
tail call void @_ZdlPv(i8* %0) nounwind // operator delete((void *)ps)
br label %delete.end
-- Jean-Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120704/4c52adca/attachment.html>
More information about the cfe-dev
mailing list