================ @@ -5635,123 +5627,95 @@ static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc, assert(Proto1 && Proto2 && "Function templates must have prototypes"); TemplateParameterList *TemplateParams = FT2->getTemplateParameters(); - SmallVector<DeducedTemplateArgument, 4> Deduced; - Deduced.resize(TemplateParams->size()); + SmallVector<DeducedTemplateArgument, 4> Deduced(TemplateParams->size()); - // C++0x [temp.deduct.partial]p3: - // The types used to determine the ordering depend on the context in which - // the partial ordering is done: TemplateDeductionInfo Info(Loc); - switch (TPOC) { - case TPOC_Call: { - llvm::SmallBitVector HasDeducedParam(Args2.size()); - if (DeduceTemplateArguments( - S, TemplateParams, Args2.data(), Args2.size(), Args1.data(), - Args1.size(), Info, Deduced, TDF_None, /*PartialOrdering=*/true, - /*HasDeducedAnyParam=*/nullptr, - &HasDeducedParam) != TemplateDeductionResult::Success) - return false; + if (TPOC == TPOC_Other) { + // We wouldn't be partial ordering these candidates if these didn't match. + assert(Proto2->getMethodQuals() == Proto1->getMethodQuals()); + assert(Proto2->getRefQualifier() == Proto1->getRefQualifier()); + assert(Proto2->isVariadic() == Proto1->isVariadic()); - SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), - Deduced.end()); - Sema::InstantiatingTemplate Inst( - S, Info.getLocation(), FT2, DeducedArgs, - Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); - if (Inst.isInvalid()) - return false; - - bool AtLeastAsSpecialized = true; - S.runWithSufficientStackSpace(Info.getLocation(), [&] { - AtLeastAsSpecialized = - ::FinishTemplateArgumentDeduction( - S, FT2, Deduced, Info, - [&](Sema &S, FunctionTemplateDecl *FTD, - ArrayRef<TemplateArgument> DeducedArgs) { - return ::DeduceForEachType( - S, TemplateParams, Args2.data(), Args2.size(), Args1.data(), - Args1.size(), Info, Deduced, - /*PartialOrdering=*/true, /*FinishingDeduction=*/true, - [&](Sema &S, TemplateParameterList *, int ParamIdx, - int ArgIdx, QualType P, QualType A, - TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - bool) { - // As a provisional fix for a core issue that does not - // exist yet, only check the consistency of parameters - // which participated in deduction. We still try to - // substitute them though. - return ::CheckDeductionConsistency( - S, FTD, ArgIdx, P, A, DeducedArgs, - HasDeducedParam[ParamIdx]); - }); - }) == TemplateDeductionResult::Success; - }); - if (!AtLeastAsSpecialized) - return false; - } break; - case TPOC_Conversion: - case TPOC_Other: { - // - In the context of a call to a conversion operator, the return types - // of the conversion function templates are used. - // - In other contexts (14.6.6.2) the function template's function type - // is used. - auto [A, P, TDF] = TPOC == TPOC_Other - ? std::make_tuple(FD1->getType(), FD2->getType(), - TDF_AllowCompatibleFunctionType) - : std::make_tuple(Proto1->getReturnType(), - Proto2->getReturnType(), TDF_None); + assert(Args1.empty() && Args2.empty()); + Args1 = Proto1->getParamTypes(); + Args2 = Proto2->getParamTypes(); + } + // C++26 [temp.deduct.partial]p3: + // The types used to determine the ordering depend on the context in which + // the partial ordering is done: + // - In the context of a function call, the types used are those function + // parameter types for which the function call has arguments. + // - In the context of a call to a conversion operator, the return types + // of the conversion function templates are used. + // - In other contexts (14.6.6.2) the function template's function type + // is used. + bool HasDeducedAnyParamFromReturnType = false; + if (TPOC != TPOC_Call) { if (DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, P, A, Info, Deduced, TDF, + S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(), + Info, Deduced, TDF_None, /*PartialOrdering=*/true, /*DeducedFromArrayBound=*/false, - /*HasDeducedAnyParam=*/nullptr) != TemplateDeductionResult::Success) + &HasDeducedAnyParamFromReturnType) != + TemplateDeductionResult::Success) return false; + } - SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), - Deduced.end()); - Sema::InstantiatingTemplate Inst( - S, Info.getLocation(), FT2, DeducedArgs, - Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); - if (Inst.isInvalid()) + llvm::SmallBitVector HasDeducedParam; + if (TPOC != TPOC_Conversion) { + HasDeducedParam.resize(Args2.size()); + if (DeduceTemplateArguments(S, TemplateParams, Args2, Args1, Info, Deduced, + TDF_None, /*PartialOrdering=*/true, + /*HasDeducedAnyParam=*/nullptr, + &HasDeducedParam) != + TemplateDeductionResult::Success) return false; + } - bool AtLeastAsSpecialized; - S.runWithSufficientStackSpace(Info.getLocation(), [&] { - AtLeastAsSpecialized = - ::FinishTemplateArgumentDeduction( - S, FT2, Deduced, Info, - [&](Sema &S, FunctionTemplateDecl *FTD, - ArrayRef<TemplateArgument> DeducedArgs) { + SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end()); + Sema::InstantiatingTemplate Inst( + S, Info.getLocation(), FT2, DeducedArgs, + Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, Info); + if (Inst.isInvalid()) + return false; + + bool AtLeastAsSpecialized; + S.runWithSufficientStackSpace(Info.getLocation(), [&] { + AtLeastAsSpecialized = + ::FinishTemplateArgumentDeduction( + S, FT2, Deduced, Info, + [&](Sema &S, FunctionTemplateDecl *FTD, + ArrayRef<TemplateArgument> DeducedArgs) { + // As a provisional fix for a core issue that does not + // exist yet, , which may be related to CWG2160, only check the ---------------- cor3ntin wrote:
```suggestion // As a provisional fix for a core issue that does not // exist yet, which may be related to CWG2160, only check the ``` https://github.com/llvm/llvm-project/pull/106829 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits