[clang] [clang] check deduction consistency when partial ordering function templates (PR #100692)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 23 06:34:15 PDT 2024
================
@@ -5421,34 +5635,139 @@ static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc,
// the partial ordering is done:
TemplateDeductionInfo Info(Loc);
switch (TPOC) {
- case TPOC_Call:
- if (DeduceTemplateArguments(S, TemplateParams, Args2.data(), Args2.size(),
- Args1.data(), Args1.size(), Info, Deduced,
- TDF_None, /*PartialOrdering=*/true) !=
- TemplateDeductionResult::Success)
+ 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;
- break;
+ 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;
- case TPOC_Conversion:
+ 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: {
// - In the context of a call to a conversion operator, the return types
// of the conversion function templates are used.
if (DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(),
Info, Deduced, TDF_None,
- /*PartialOrdering=*/true) != TemplateDeductionResult::Success)
+ /*PartialOrdering=*/true, /*DeducedFromArrayBound=*/false,
+ /*HasDeducedAnyParam=*/nullptr) != TemplateDeductionResult::Success)
return false;
- break;
- case TPOC_Other:
+ 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) {
+ return ::CheckDeductionConsistency(
+ S, FTD, /*ArgIdx=*/-1, Proto2->getReturnType(),
+ Proto1->getReturnType(), DeducedArgs,
+ /*CheckConsistency=*/true);
+ }) == TemplateDeductionResult::Success;
+ });
+ if (!AtLeastAsSpecialized)
+ return false;
+ } break;
+
+ case TPOC_Other: {
// - In other contexts (14.6.6.2) the function template's function type
// is used.
if (DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced,
TDF_AllowCompatibleFunctionType,
- /*PartialOrdering=*/true) != TemplateDeductionResult::Success)
+ /*PartialOrdering=*/true, /*DeducedFromArrayBound=*/false,
+ /*HasDeducedAnyParam=*/nullptr) != TemplateDeductionResult::Success)
return false;
- break;
+
+ 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) {
+ if (auto TDR = ::CheckDeductionConsistency(
+ S, FTD, /*ArgIdx=*/-1, Proto2->getReturnType(),
+ Proto1->getReturnType(), DeducedArgs,
+ /*CheckConsistency=*/true);
+ TDR != TemplateDeductionResult::Success)
+ return TDR;
+ return ::DeduceForEachType(
+ S, TemplateParams, Proto2->getParamTypes().data(),
+ Proto2->getParamTypes().size(),
+ Proto1->getParamTypes().data(),
+ Proto1->getParamTypes().size(), Info, Deduced,
+ /*PartialOrdering=*/true, /*FinishingDeduction=*/true,
+ [&](Sema &S, TemplateParameterList *, int ParamIdx,
+ int ArgIdx, QualType P, QualType A,
+ TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ bool) {
+ return ::CheckDeductionConsistency(
+ S, FTD, ArgIdx, P, A, DeducedArgs,
+ /*CheckConsistency=*/true);
+ });
+ }) == TemplateDeductionResult::Success;
+ });
+ if (!AtLeastAsSpecialized)
+ return false;
+ } break;
----------------
cor3ntin wrote:
Look quite similar to the code above, any chance we can refactor?
https://github.com/llvm/llvm-project/pull/100692
More information about the cfe-commits
mailing list