Perform overload resolution when selecting a pointer conversion
function for delete of a class expression and issue
good diagnostic when result is ambiguous.
llvm-svn: 81870
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ec7b2c8..9005566 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -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();
}
}