[cfe-commits] r81870 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp test/SemaCXX/conversion-delete-expr.cpp test/SemaCXX/new-delete.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Sep 15 13:46:26 PDT 2009


On Sep 15, 2009, at 1:23 PM, Douglas Gregor wrote:

>
> On Sep 15, 2009, at 10:21 AM, Fariborz Jahanian wrote:
>
>> Author: fjahanian
>> Date: Tue Sep 15 12:21:47 2009
>> New Revision: 81870
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=81870&view=rev
>> Log:
>> Perform overload resolution when selecting a pointer conversion
>> function for delete of a class expression and issue
>> good diagnostic when result is ambiguous.
>>
>> Modified:
>>   cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>   cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>   cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp
>>   cfe/trunk/test/SemaCXX/new-delete.cpp
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81870&r1=81869&r2=81870&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 15  
>> 12:21:47 2009
>> @@ -1558,6 +1558,8 @@
>> def err_new_uninitialized_const : Error<
>>  "must provide an initializer if the allocated object is 'const'">;
>> def err_delete_operand : Error<"cannot delete expression of type  
>> %0">;
>> +def err_ambiguous_delete_operand : Error<"ambiguous conversion of  
>> delete "
>> +                                         "expression of type %0 to  
>> a pointer">;
>> def warn_delete_incomplete : Warning<
>>  "deleting pointer to incomplete type %0 may cause undefined  
>> behaviour">;
>> def err_decrement_bool : Error<"cannot decrement expression of type  
>> bool">;
>>
>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81870&r1=81869&r2=81870&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Sep 15 12:21:47 2009
>> @@ -736,6 +736,7 @@
>>    QualType Type = Ex->getType();
>>
>>    if (const RecordType *Record = Type->getAs<RecordType>()) {
>> +      OverloadCandidateSet CandidateSet;
>>      llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
>>      CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
>>      OverloadedFunctionDecl *Conversions =
>> @@ -754,20 +755,32 @@
>>        QualType ConvType = Conv- 
>> >getConversionType().getNonReferenceType();
>>        if (const PointerType *ConvPtrType = ConvType- 
>> >getAs<PointerType>())
>>          if (ConvPtrType->getPointeeType()->isObjectType())
>> -            ObjectPtrConversions.push_back(Conv);
>> +            AddConversionCandidate(Conv, Ex, ConvType,  
>> CandidateSet);
>>      }
>> -
>> -      if (ObjectPtrConversions.size() == 1) {
>> -        // We have a single conversion to a pointer-to-object  
>> type. Perform
>> -        // that conversion.
>> -        Operand.release();
>> -        if (PerformImplicitConversion(Ex,
>> -                            ObjectPtrConversions.front()- 
>> >getConversionType(),
>> -                                      "converting"))
>> +      OverloadCandidateSet::iterator Best;
>> +      switch (BestViableFunction(CandidateSet, Ex->getLocStart(),  
>> Best)) {
>> +        case OR_Success:
>> +          {
>> +            Operand.release();
>> +            CXXConversionDecl *Conversion
>> +              = cast<CXXConversionDecl>(Best->Function);
>> +            if (PerformImplicitConversion(Ex,
>> +                                          Conversion- 
>> >getConversionType(),
>> +                                          "converting"))
>> +              return ExprError();
>> +
>> +            Operand = Owned(Ex);
>> +            Type = Ex->getType();
>> +            break;
>> +          }
>> +        case OR_No_Viable_Function:
>> +        case OR_Deleted:
>> +          break;  // Will issue error below.
>> +        case OR_Ambiguous:
>> +          Diag(StartLoc, diag::err_ambiguous_delete_operand)
>> +                  << Type << Ex->getSourceRange();
>> +          PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/ 
>> false);
>>          return ExprError();
>> -
>> -        Operand = Owned(Ex);
>> -        Type = Ex->getType();
>>      }
>>    }
>
> Why are we trying to perform overload resolution here? C++  
> [expr.delete]p1 is pretty clear that delete only works when there is  
> a single conversion function to a pointer-to-object type; it doesn't  
> mention overload resolution at all.
Yes. But we still have to find it and in the course of finding it, we  
may have ambiguity; as in this example:

struct Base {
	operator int*();
};
struct Base1 {
	operator int*();
};


struct Derived : Base,  Base1{
};

void foo6(Derived d) {
	delete d;
}

I also had this example in mind:

struct Base {
    operator int*() const;
};

struct Derived : Base {
    operator int*();
};

void foo6(const Derived cd) {
	delete cd;
}
If in this example, we are mandated to select Derived::operator  
int*(), over Base::operator int*() (which to me is illogical), then I  
need to make
adjustments.
- Fariborz

>
>
> 	- Doug




More information about the cfe-commits mailing list