From: Richard Smith Date: Tue, 10 Jan 2017 20:19:21 +0000 (+0000) Subject: Fix conversion index / argument index mismatch when diagnosing overload resolution... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=770a04d6da276f36531373d590310d04082e6a4f;p=clang 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 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 41f4fa746f..514b4af1c9 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 ParamTypes; if (Cand->IsSurrogate) { QualType ConvType = Cand->Surrogate->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs()) ConvType = ConvPtrType->getPointeeType(); - Proto = ConvType->getAs(); - ArgIdx = 1; + ParamTypes = ConvType->getAs()->getParamTypes(); + // Conversion 0 is 'this', which doesn't have a corresponding argument. + ConvIdx = 1; } else if (Cand->Function) { - Proto = Cand->Function->getType()->getAs(); + ParamTypes = + Cand->Function->getType()->getAs()->getParamTypes(); if (isa(Cand->Function) && - !isa(Cand->Function)) - ArgIdx = 1; + !isa(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 0c0e7d599c..419464447d 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -383,6 +383,12 @@ namespace deduction_after_explicit_pack { template struct X { X(int); operator int(); }; template void p(T..., X, ...); // expected-note {{deduced conflicting}} void q() { p(X(0), 0); } // expected-error {{no match}} + + struct A { + template 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 {