r291596 - Fix conversion index / argument index mismatch when diagnosing overload resolution failure.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 10 12:19:21 PST 2017


Author: rsmith
Date: Tue Jan 10 14:19:21 2017
New Revision: 291596

URL: http://llvm.org/viewvc/llvm-project?rev=291596&view=rev
Log:
Fix conversion index / argument index mismatch when diagnosing overload resolution failure.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaTemplate/deduction.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=291596&r1=291595&r2=291596&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jan 10 14:19:21 2017
@@ -10490,56 +10490,42 @@ static void CompleteNonViableCandidate(S
   // 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=*/

Modified: cfe/trunk/test/SemaTemplate/deduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/deduction.cpp?rev=291596&r1=291595&r2=291596&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/deduction.cpp (original)
+++ cfe/trunk/test/SemaTemplate/deduction.cpp Tue Jan 10 14:19:21 2017
@@ -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 {




More information about the cfe-commits mailing list