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();
       }
     }