Skip to content

Commit 27a01f6

Browse files
authored
[clang] correct argument offset for function template partial ordering (#107972)
1 parent 6dacc38 commit 27a01f6

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

clang/lib/Sema/SemaTemplateDeduction.cpp

+14-14
Original file line numberDiff line numberDiff line change
@@ -5502,10 +5502,6 @@ static TemplateDeductionResult CheckDeductionConsistency(
55025502
ArrayRef<TemplateArgument> DeducedArgs, bool CheckConsistency) {
55035503
MultiLevelTemplateArgumentList MLTAL(FTD, DeducedArgs,
55045504
/*Final=*/true);
5505-
if (ArgIdx != -1)
5506-
if (auto *MD = dyn_cast<CXXMethodDecl>(FTD->getTemplatedDecl());
5507-
MD && MD->isImplicitObjectMemberFunction())
5508-
ArgIdx -= 1;
55095505
Sema::ArgumentPackSubstitutionIndexRAII PackIndex(
55105506
S, ArgIdx != -1 ? ::getPackIndexForParam(S, FTD, MLTAL, ArgIdx) : -1);
55115507
bool IsIncompleteSubstitution = false;
@@ -5576,12 +5572,10 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
55765572

55775573
/// Determine whether the function template \p FT1 is at least as
55785574
/// specialized as \p FT2.
5579-
static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc,
5580-
FunctionTemplateDecl *FT1,
5581-
FunctionTemplateDecl *FT2,
5582-
TemplatePartialOrderingContext TPOC,
5583-
ArrayRef<QualType> Args1,
5584-
ArrayRef<QualType> Args2) {
5575+
static bool isAtLeastAsSpecializedAs(
5576+
Sema &S, SourceLocation Loc, FunctionTemplateDecl *FT1,
5577+
FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC,
5578+
ArrayRef<QualType> Args1, ArrayRef<QualType> Args2, bool Args1Offset) {
55855579
FunctionDecl *FD1 = FT1->getTemplatedDecl();
55865580
FunctionDecl *FD2 = FT2->getTemplatedDecl();
55875581
const FunctionProtoType *Proto1 = FD1->getType()->getAs<FunctionProtoType>();
@@ -5676,6 +5670,8 @@ static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc,
56765670
TemplateDeductionInfo &Info,
56775671
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
56785672
PartialOrderingKind) {
5673+
if (ArgIdx != -1)
5674+
ArgIdx -= Args1Offset;
56795675
return ::CheckDeductionConsistency(
56805676
S, FTD, ArgIdx, P, A, DeducedArgs,
56815677
/*CheckConsistency=*/HasDeducedParam[ParamIdx]);
@@ -5763,6 +5759,8 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
57635759
const FunctionDecl *FD2 = FT2->getTemplatedDecl();
57645760
bool ShouldConvert1 = false;
57655761
bool ShouldConvert2 = false;
5762+
bool Args1Offset = false;
5763+
bool Args2Offset = false;
57665764
QualType Obj1Ty;
57675765
QualType Obj2Ty;
57685766
if (TPOC == TPOC_Call) {
@@ -5811,6 +5809,7 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
58115809
Obj1Ty = GetImplicitObjectParameterType(this->Context, Method1,
58125810
RawObj1Ty, IsRValRef2);
58135811
Args1.push_back(Obj1Ty);
5812+
Args1Offset = true;
58145813
}
58155814
if (ShouldConvert2) {
58165815
bool IsRValRef1 =
@@ -5821,6 +5820,7 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
58215820
Obj2Ty = GetImplicitObjectParameterType(this->Context, Method2,
58225821
RawObj2Ty, IsRValRef1);
58235822
Args2.push_back(Obj2Ty);
5823+
Args2Offset = true;
58245824
}
58255825
} else {
58265826
if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
@@ -5842,10 +5842,10 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
58425842
} else {
58435843
assert(!Reversed && "Only call context could have reversed arguments");
58445844
}
5845-
bool Better1 =
5846-
isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, Args1, Args2);
5847-
bool Better2 =
5848-
isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, Args2, Args1);
5845+
bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, Args1,
5846+
Args2, Args2Offset);
5847+
bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, Args2,
5848+
Args1, Args1Offset);
58495849
// C++ [temp.deduct.partial]p10:
58505850
// F is more specialized than G if F is at least as specialized as G and G
58515851
// is not at least as specialized as F.

clang/test/SemaTemplate/GH18291.cpp

+26-1
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,29 @@ namespace func_pointer {
8686
template <class _Tp> void pow(_Tp, complex<typename __promote<_Tp>::type>) = delete;
8787
void (*ptr)(const complex<float> &, complex<float>){pow};
8888
} // namespace param
89-
} // namespace t3
89+
} // namespace func_pointer
90+
91+
namespace static_vs_nonstatic {
92+
namespace implicit_obj_param {
93+
struct A {
94+
template <class... Args>
95+
static void f(int a, Args... args) {}
96+
template <class... Args>
97+
void f(Args... args) = delete;
98+
};
99+
void g(){
100+
A::f(0);
101+
}
102+
} // namespace implicit_obj_param
103+
namespace explicit_obj_param {
104+
struct A {
105+
template <class... Args>
106+
static void f(int, Args... args) {}
107+
template <class... Args>
108+
void f(this A *, Args... args) = delete;
109+
};
110+
void g(){
111+
A::f(0);
112+
}
113+
} // namespace explicit_obj_param
114+
} // namespace static_vs_nonstatic

0 commit comments

Comments
 (0)