[clang] [clang] function template non-call partial ordering fixes (PR #106829)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 31 02:36:03 PDT 2024
================
@@ -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:
Can you send a message to core?
https://github.com/llvm/llvm-project/pull/106829
More information about the cfe-commits
mailing list