[cfe-dev] Why the argument of `delete' is converted to void* ?

Enea Zaffanella zaffanella at cs.unipr.it
Wed Jul 4 06:57:28 PDT 2012


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.



More information about the cfe-dev mailing list