[clang] [clang-tools-extra] [clang] check deduction consistency when partial ordering function templates (PR #100692)
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 26 11:31:58 PDT 2024
================
@@ -5425,34 +5534,112 @@ static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc,
// the partial ordering is done:
TemplateDeductionInfo Info(Loc);
switch (TPOC) {
- case TPOC_Call:
+ case TPOC_Call: {
if (DeduceTemplateArguments(S, TemplateParams, Args2.data(), Args2.size(),
Args1.data(), Args1.size(), Info, Deduced,
TDF_None, /*PartialOrdering=*/true) !=
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 =
+ ::DeduceForEachType(
+ S, TemplateParams, Args2.data(), Args2.size(), Args1.data(),
+ Args1.size(), Info, Deduced,
+ /*PartialOrdering=*/true, /*FinishingDeduction=*/true,
+ [&FT2](Sema &S, TemplateParameterList *, int ArgIdx, QualType P,
+ QualType A, TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ bool PartialOrdering) {
+ return ::FinishTemplateArgumentDeduction(S, FT2, ArgIdx, P, A,
+ Deduced, Info);
+ }) == 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)
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, /*ArgIdx=*/-1, Proto2->getReturnType(),
+ Proto1->getReturnType(), Deduced,
+ Info) == 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)
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, /*ArgIdx=*/-1, Proto2->getReturnType(),
+ Proto1->getReturnType(), Deduced,
+ Info) == TemplateDeductionResult::Success;
+ if (!AtLeastAsSpecialized)
+ return;
+ S.runWithSufficientStackSpace(Info.getLocation(), [&] {
+ AtLeastAsSpecialized =
+ ::DeduceForEachType(
+ S, TemplateParams, Proto2->getParamTypes().data(),
+ Proto2->getParamTypes().size(), Proto1->getParamTypes().data(),
+ Proto1->getParamTypes().size(), Info, Deduced,
+ /*PartialOrdering=*/true, /*FinishingDeduction=*/true,
+ [&FT2](Sema &S, TemplateParameterList *, int ArgIdx, QualType P,
+ QualType A, TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ bool PartialOrdering) {
+ return ::FinishTemplateArgumentDeduction(S, FT2, ArgIdx, P, A,
+ Deduced, Info);
+ }) == TemplateDeductionResult::Success;
+ });
+ });
----------------
zygoloid wrote:
Do we need to separately check the return type and the parameter types here, rather than checking the entire function type as a whole? (This is not quite the same: for example, checking the whole function type would also consider the exception specification.)
https://github.com/llvm/llvm-project/pull/100692
More information about the cfe-commits
mailing list