[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