diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 257 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 36 |
2 files changed, 85 insertions, 208 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a2ee2b00ecf..47e3df20d91 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -589,6 +589,7 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, Result.Result = static_cast<unsigned>(TDK); Result.HasDiagnostic = false; switch (TDK) { + case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: @@ -647,10 +648,6 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, case Sema::TDK_FailedOverloadResolution: Result.Data = Info.Expression; break; - - case Sema::TDK_Success: - case Sema::TDK_NonDependentConversionFailure: - llvm_unreachable("not a deduction failure"); } return Result; @@ -667,7 +664,6 @@ void DeductionFailureInfo::Destroy() { case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_FailedOverloadResolution: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: break; case Sema::TDK_Inconsistent: @@ -711,7 +707,6 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { case Sema::TDK_NonDeducedMismatch: case Sema::TDK_FailedOverloadResolution: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return TemplateParameter(); case Sema::TDK_Incomplete: @@ -744,7 +739,6 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { case Sema::TDK_NonDeducedMismatch: case Sema::TDK_FailedOverloadResolution: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_DeducedMismatch: @@ -773,7 +767,6 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { case Sema::TDK_SubstitutionFailure: case Sema::TDK_FailedOverloadResolution: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_Inconsistent: @@ -802,7 +795,6 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { case Sema::TDK_SubstitutionFailure: case Sema::TDK_FailedOverloadResolution: case Sema::TDK_CUDATargetMismatch: - case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_Inconsistent: @@ -837,8 +829,8 @@ llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() { void OverloadCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { - for (auto &C : i->Conversions) - C.~ImplicitConversionSequence(); + for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii) + i->Conversions[ii].~ImplicitConversionSequence(); if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction) i->DeductionFailure.Destroy(); } @@ -5845,8 +5837,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, - bool AllowExplicit, - ConversionSequenceList EarlyConversions) { + bool AllowExplicit) { const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>()); assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -5865,7 +5856,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), Expr::Classification::makeSimpleLValue(), Args, CandidateSet, SuppressUserConversions, - PartialOverloading, EarlyConversions); + PartialOverloading); return; } // We treat a constructor like a non-member function, since its object @@ -5898,8 +5889,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); // Add this candidate - OverloadCandidate &Candidate = - CandidateSet.addCandidate(Args.size(), EarlyConversions); + OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); Candidate.FoundDecl = FoundDecl; Candidate.Function = Function; Candidate.Viable = true; @@ -5963,10 +5953,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { - if (Candidate.Conversions[ArgIdx].isInitialized()) { - // We already formed a conversion sequence for this parameter during - // template argument deduction. - } else if (ArgIdx < NumParams) { + if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding @@ -6275,8 +6262,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, - bool PartialOverloading, - ConversionSequenceList EarlyConversions) { + bool PartialOverloading) { const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>()); assert(Proto && "Methods without a prototype cannot be overloaded"); @@ -6297,8 +6283,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); // Add this candidate - OverloadCandidate &Candidate = - CandidateSet.addCandidate(Args.size() + 1, EarlyConversions); + OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1); Candidate.FoundDecl = FoundDecl; Candidate.Function = Method; Candidate.IsSurrogate = false; @@ -6360,10 +6345,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { - if (Candidate.Conversions[ArgIdx + 1].isInitialized()) { - // We already formed a conversion sequence for this parameter during - // template argument deduction. - } else if (ArgIdx < NumParams) { + if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding @@ -6424,30 +6406,19 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; - ConversionSequenceList Conversions; - if (TemplateDeductionResult Result = DeduceTemplateArguments( - MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info, - PartialOverloading, [&]() { - return CheckNonDependentConversions( - MethodTmpl, Args, CandidateSet, Conversions, - SuppressUserConversions, ActingContext, ObjectType, - ObjectClassification); - })) { - OverloadCandidate &Candidate = - CandidateSet.addCandidate(Conversions.size(), Conversions); + if (TemplateDeductionResult Result + = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args, + Specialization, Info, PartialOverloading)) { + OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = MethodTmpl->getTemplatedDecl(); Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); - if (Result == TDK_NonDependentConversionFailure) - Candidate.FailureKind = ovl_fail_bad_conversion; - else { - Candidate.FailureKind = ovl_fail_bad_deduction; - Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, - Info); - } + Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, + Info); return; } @@ -6458,8 +6429,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, "Specialization is not a member function?"); AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, - CandidateSet, SuppressUserConversions, PartialOverloading, - Conversions); + CandidateSet, SuppressUserConversions, PartialOverloading); } /// \brief Add a C++ function template specialization as a candidate @@ -6487,29 +6457,19 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; - ConversionSequenceList Conversions; - if (TemplateDeductionResult Result = DeduceTemplateArguments( - FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info, - PartialOverloading, [&]() { - return CheckNonDependentConversions(FunctionTemplate, Args, - CandidateSet, Conversions, - SuppressUserConversions); - })) { - OverloadCandidate &Candidate = - CandidateSet.addCandidate(Conversions.size(), Conversions); + if (TemplateDeductionResult Result + = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args, + Specialization, Info, PartialOverloading)) { + OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); - if (Result == TDK_NonDependentConversionFailure) - Candidate.FailureKind = ovl_fail_bad_conversion; - else { - Candidate.FailureKind = ovl_fail_bad_deduction; - Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, - Info); - } + Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, + Info); return; } @@ -6517,64 +6477,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, // deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet, - SuppressUserConversions, PartialOverloading, - /*AllowExplicit*/false, Conversions); -} - -/// Check that implicit conversion sequences can be formed for each argument -/// whose corresponding parameter has a non-dependent type, per DR1391's -/// [temp.deduct.call]p10. -bool Sema::CheckNonDependentConversions( - FunctionTemplateDecl *FunctionTemplate, ArrayRef<Expr *> Args, - OverloadCandidateSet &CandidateSet, ConversionSequenceList &Conversions, - bool SuppressUserConversions, CXXRecordDecl *ActingContext, - QualType ObjectType, Expr::Classification ObjectClassification) { - // FIXME: The cases in which we allow explicit conversions for constructor - // arguments never consider calling a constructor template. It's not clear - // that is correct. - const bool AllowExplicit = false; - - auto *FD = FunctionTemplate->getTemplatedDecl(); - auto *Method = dyn_cast<CXXMethodDecl>(FD); - bool HasThisConversion = Method && !isa<CXXConstructorDecl>(Method); - unsigned ThisConversions = HasThisConversion ? 1 : 0; - - Conversions = - CandidateSet.allocateConversionSequences(ThisConversions + Args.size()); - - // Overload resolution is always an unevaluated context. - EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); - - // For a method call, check the 'this' conversion here too. DR1391 doesn't - // require that, but this check should never result in a hard error, and - // overload resolution is permitted to sidestep instantiations. - if (HasThisConversion && !cast<CXXMethodDecl>(FD)->isStatic() && - !ObjectType.isNull()) { - Conversions[0] = TryObjectArgumentInitialization( - *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, - Method, ActingContext); - if (Conversions[0].isBad()) - return true; - } - - - for (unsigned I = 0, N = std::min<unsigned>(FD->getNumParams(), Args.size()); - I != N; ++I) { - QualType ParamType = FD->getParamDecl(I)->getType(); - if (!ParamType->isDependentType()) { - Conversions[ThisConversions + I] - = TryCopyInitialization(*this, Args[I], ParamType, - SuppressUserConversions, - /*InOverloadResolution=*/true, - /*AllowObjCWritebackConversion=*/ - getLangOpts().ObjCAutoRefCount, - AllowExplicit); - if (Conversions[ThisConversions + I].isBad()) - return true; - } - } - - return false; + SuppressUserConversions, PartialOverloading); } /// Determine whether this is an allowable conversion from the result @@ -8813,8 +8716,8 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, // Define functions that don't require ill-formed conversions for a given // argument to be better candidates than functions that do. - unsigned NumArgs = Cand1.Conversions.size(); - assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch"); + unsigned NumArgs = Cand1.NumConversions; + assert(Cand2.NumConversions == NumArgs && "Overload candidate mismatch"); bool HasBetterConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]); @@ -10021,7 +9924,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, case ovl_fail_bad_conversion: { unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); - for (unsigned N = Cand->Conversions.size(); I != N; ++I) + for (unsigned N = Cand->NumConversions; I != N; ++I) if (Cand->Conversions[I].isBad()) return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress); @@ -10084,12 +9987,12 @@ static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, SourceLocation OpLoc, OverloadCandidate *Cand) { - assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary"); + assert(Cand->NumConversions <= 2 && "builtin operator is not binary"); std::string TypeStr("operator"); TypeStr += Opc; TypeStr += "("; TypeStr += Cand->BuiltinTypes.ParamTypes[0].getAsString(); - if (Cand->Conversions.size() == 1) { + if (Cand->NumConversions == 1) { TypeStr += ")"; S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr; } else { @@ -10102,7 +10005,9 @@ static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, OverloadCandidate *Cand) { - for (const ImplicitConversionSequence &ICS : Cand->Conversions) { + unsigned NoOperands = Cand->NumConversions; + for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) { + const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx]; if (ICS.isBad()) break; // all meaningless after first invalid if (!ICS.isAmbiguous()) continue; @@ -10122,8 +10027,7 @@ static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) { static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { switch ((Sema::TemplateDeductionResult)DFI.Result) { case Sema::TDK_Success: - case Sema::TDK_NonDependentConversionFailure: - llvm_unreachable("non-deduction failure while diagnosing bad deduction"); + llvm_unreachable("TDK_success while diagnosing bad deduction"); case Sema::TDK_Invalid: case Sema::TDK_Incomplete: @@ -10226,11 +10130,11 @@ struct CompareOverloadCandidatesForDisplay { // If there's any ordering between the defined conversions... // FIXME: this might not be transitive. - assert(L->Conversions.size() == R->Conversions.size()); + assert(L->NumConversions == R->NumConversions); int leftBetter = 0; unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument); - for (unsigned E = L->Conversions.size(); I != E; ++I) { + for (unsigned E = L->NumConversions; I != E; ++I) { switch (CompareImplicitConversionSequences(S, Loc, L->Conversions[I], R->Conversions[I])) { @@ -10279,8 +10183,7 @@ struct CompareOverloadCandidatesForDisplay { } /// CompleteNonViableCandidate - Normally, overload resolution only -/// computes up to the first bad conversion. Produces the FixIt set if -/// possible. +/// computes up to the first. Produces the FixIt set if possible. static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, ArrayRef<Expr *> Args) { assert(!Cand->Viable); @@ -10293,24 +10196,30 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, // Use a implicit copy initialization to check conversion fixes. Cand->Fix.setConversionChecker(TryCopyInitialization); - // Attempt to fix the bad conversion. - unsigned ConvCount = Cand->Conversions.size(); - for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/; - ++ConvIdx) { + // Skip forward to the first bad conversion. + unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); + unsigned ConvCount = Cand->NumConversions; + while (true) { assert(ConvIdx != ConvCount && "no bad conversion in candidate"); - if (Cand->Conversions[ConvIdx].isInitialized() && - Cand->Conversions[ConvIdx].isBad()) { - Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); + ConvIdx++; + if (Cand->Conversions[ConvIdx - 1].isBad()) { + Unfixable = !Cand->TryToFixBadConversion(ConvIdx - 1, S); break; } } + if (ConvIdx == ConvCount) + return; + + assert(!Cand->Conversions[ConvIdx].isInitialized() && + "remaining conversion is initialized?"); + // FIXME: this should probably be preserved from the overload // operation somehow. bool SuppressUserConversions = false; - const FunctionProtoType *Proto; - unsigned ArgIdx = 0; + const FunctionProtoType* Proto; + unsigned ArgIdx = ConvIdx; if (Cand->IsSurrogate) { QualType ConvType @@ -10318,56 +10227,40 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) ConvType = ConvPtrType->getPointeeType(); Proto = ConvType->getAs<FunctionProtoType>(); - ArgIdx = 1; + ArgIdx--; } else if (Cand->Function) { Proto = Cand->Function->getType()->getAs<FunctionProtoType>(); if (isa<CXXMethodDecl>(Cand->Function) && !isa<CXXConstructorDecl>(Cand->Function)) - ArgIdx = 1; + ArgIdx--; } else { // Builtin binary operator with a bad first conversion. 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. - } + for (; ConvIdx != ConvCount; ++ConvIdx) + Cand->Conversions[ConvIdx] + = TryCopyInitialization(S, Args[ConvIdx], + Cand->BuiltinTypes.ParamTypes[ConvIdx], + SuppressUserConversions, + /*InOverloadResolution*/ true, + /*AllowObjCWritebackConversion=*/ + S.getLangOpts().ObjCAutoRefCount); return; } // Fill in the rest of the conversions. unsigned NumParams = Proto->getNumParams(); - for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); - ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { - if (Cand->Conversions[ConvIdx].isInitialized()) { - // Found the bad conversion. - } else if (ArgIdx < NumParams) { - if (Proto->getParamType(ArgIdx)->isDependentType()) - Cand->Conversions[ConvIdx].setAsIdentityConversion( - Args[ArgIdx]->getType()); - else { - Cand->Conversions[ConvIdx] = - TryCopyInitialization(S, Args[ArgIdx], Proto->getParamType(ArgIdx), - SuppressUserConversions, - /*InOverloadResolution=*/true, - /*AllowObjCWritebackConversion=*/ - S.getLangOpts().ObjCAutoRefCount); - // Store the FixIt in the candidate if it exists. - if (!Unfixable && Cand->Conversions[ConvIdx].isBad()) - Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); - } - } else + for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { + if (ArgIdx < NumParams) { + Cand->Conversions[ConvIdx] = TryCopyInitialization( + S, Args[ArgIdx], Proto->getParamType(ArgIdx), SuppressUserConversions, + /*InOverloadResolution=*/true, + /*AllowObjCWritebackConversion=*/ + S.getLangOpts().ObjCAutoRefCount); + // Store the FixIt in the candidate if it exists. + if (!Unfixable && Cand->Conversions[ConvIdx].isBad()) + Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); + } + else Cand->Conversions[ConvIdx].setEllipsis(); } } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index dc291836fb9..0bc85a2f263 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2849,13 +2849,14 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg, /// /// \param OriginalCallArgs If non-NULL, the original call arguments against /// which the deduced argument types should be compared. -Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( - FunctionTemplateDecl *FunctionTemplate, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, - TemplateDeductionInfo &Info, - SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs, - bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) { +Sema::TemplateDeductionResult +Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, + unsigned NumExplicitlySpecified, + FunctionDecl *&Specialization, + TemplateDeductionInfo &Info, + SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs, + bool PartialOverloading) { // Unevaluated SFINAE context. EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); SFINAETrap Trap(*this); @@ -2882,18 +2883,6 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( PartialOverloading)) return Result; - // C++ [temp.deduct.call]p10: [DR1391] - // If deduction succeeds for all parameters that contain - // template-parameters that participate in template argument deduction, - // and all template arguments are explicitly specified, deduced, or - // obtained from default template arguments, remaining parameters are then - // compared with the corresponding arguments. For each remaining parameter - // P with a type that was non-dependent before substitution of any - // explicitly-specified template arguments, if the corresponding argument - // A cannot be implicitly converted to P, deduction fails. - if (CheckNonDependent()) - return TDK_NonDependentConversionFailure; - // Form the template argument list from the deduced template arguments. TemplateArgumentList *DeducedArgumentList = TemplateArgumentList::CreateCopy(Context, Builder); @@ -3318,17 +3307,12 @@ DeduceTemplateArgumentByListElement(Sema &S, /// \param Info the argument will be updated to provide additional information /// about template argument deduction. /// -/// \param CheckNonDependent A callback to invoke to check conversions for -/// non-dependent parameters, between deduction and substitution, per DR1391. -/// If this returns true, substitution will be skipped and we return -/// TDK_NonDependentConversionFailure. -/// /// \returns the result of template argument deduction. Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, FunctionDecl *&Specialization, TemplateDeductionInfo &Info, - bool PartialOverloading, llvm::function_ref<bool()> CheckNonDependent) { + bool PartialOverloading) { if (FunctionTemplate->isInvalidDecl()) return TDK_Invalid; @@ -3512,7 +3496,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, &OriginalCallArgs, - PartialOverloading, CheckNonDependent); + PartialOverloading); } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, |

