From 770a04d6da276f36531373d590310d04082e6a4f Mon Sep 17 00:00:00 2001
From: Richard Smith <richard-llvm@metafoo.co.uk>
Date: Tue, 10 Jan 2017 20:19:21 +0000
Subject: [PATCH] Fix conversion index / argument index mismatch when
 diagnosing overload resolution failure.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291596 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaOverload.cpp       | 50 ++++++++++++---------------------
 test/SemaTemplate/deduction.cpp |  6 ++++
 2 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 41f4fa746fc..514b4af1c94 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -10490,56 +10490,42 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
   // operation somehow.
   bool SuppressUserConversions = false;
 
-  const FunctionProtoType *Proto;
-  unsigned ArgIdx = 0;
+  unsigned ConvIdx = 0;
+  ArrayRef<QualType> ParamTypes;
 
   if (Cand->IsSurrogate) {
     QualType ConvType
       = Cand->Surrogate->getConversionType().getNonReferenceType();
     if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
       ConvType = ConvPtrType->getPointeeType();
-    Proto = ConvType->getAs<FunctionProtoType>();
-    ArgIdx = 1;
+    ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes();
+    // Conversion 0 is 'this', which doesn't have a corresponding argument.
+    ConvIdx = 1;
   } else if (Cand->Function) {
-    Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
+    ParamTypes =
+        Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes();
     if (isa<CXXMethodDecl>(Cand->Function) &&
-        !isa<CXXConstructorDecl>(Cand->Function))
-      ArgIdx = 1;
+        !isa<CXXConstructorDecl>(Cand->Function)) {
+      // Conversion 0 is 'this', which doesn't have a corresponding argument.
+      ConvIdx = 1;
+    }
   } else {
-    // Builtin binary operator with a bad first conversion.
+    // Builtin operator.
     assert(ConvCount <= 3);
-    for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
-         ConvIdx != ConvCount; ++ConvIdx) {
-      if (Cand->Conversions[ConvIdx].isInitialized())
-        continue;
-      if (Cand->BuiltinTypes.ParamTypes[ConvIdx]->isDependentType())
-        Cand->Conversions[ConvIdx].setAsIdentityConversion(
-            Args[ConvIdx]->getType());
-      else
-        Cand->Conversions[ConvIdx] = TryCopyInitialization(
-            S, Args[ConvIdx], Cand->BuiltinTypes.ParamTypes[ConvIdx],
-            SuppressUserConversions,
-            /*InOverloadResolution*/ true,
-            /*AllowObjCWritebackConversion=*/
-            S.getLangOpts().ObjCAutoRefCount);
-      // FIXME: If the conversion is bad, try to fix it.
-    }
-    return;
+    ParamTypes = Cand->BuiltinTypes.ParamTypes;
   }
 
   // Fill in the rest of the conversions.
-  unsigned NumParams = Proto->getNumParams();
-  for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
-       ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
+  for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
     if (Cand->Conversions[ConvIdx].isInitialized()) {
-      // Found the bad conversion.
-    } else if (ArgIdx < NumParams) {
-      if (Proto->getParamType(ArgIdx)->isDependentType())
+      // We've already checked this conversion.
+    } else if (ArgIdx < ParamTypes.size()) {
+      if (ParamTypes[ArgIdx]->isDependentType())
         Cand->Conversions[ConvIdx].setAsIdentityConversion(
             Args[ArgIdx]->getType());
       else {
         Cand->Conversions[ConvIdx] =
-            TryCopyInitialization(S, Args[ArgIdx], Proto->getParamType(ArgIdx),
+            TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx],
                                   SuppressUserConversions,
                                   /*InOverloadResolution=*/true,
                                   /*AllowObjCWritebackConversion=*/
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
index 0c0e7d599cc..419464447d5 100644
--- a/test/SemaTemplate/deduction.cpp
+++ b/test/SemaTemplate/deduction.cpp
@@ -383,6 +383,12 @@ namespace deduction_after_explicit_pack {
   template<typename... T> struct X { X(int); operator int(); };
   template<typename... T> void p(T..., X<T...>, ...); // expected-note {{deduced conflicting}}
   void q() { p(X<int>(0), 0); } // expected-error {{no match}}
+
+  struct A {
+    template <typename T> void f(T, void *, int = 0); // expected-note {{no known conversion from 'double' to 'void *' for 2nd argument}}
+    void f(); // expected-note {{requires 0}}
+  };
+  void f(A a) { a.f(1.0, 2.0); } // expected-error {{no match}}
 }
 
 namespace overload_vs_pack {
-- 
GitLab