Skip to content

Commit 4c0a7b7

Browse files
authored
[clang] Distinguish NTTPs with deduced types in variable template partial specializations (#152864)
If a template argument in a partial specialization of a variable template directly refers to a NTTP of the specialization without implicit type conversion it was assumed that the NTTP is identical to that of the primary template. This doesn't hold if the primary template's NTTP uses a deduced type, so instead compare the types explicitly as well. The affected function is used only to provide an improved early error if the partial specialization has identical template arguments to the primary template. The actual check that the partial specialization is more specialized happens later. Fixes #118190 Fixes #152750
1 parent f94d809 commit 4c0a7b7

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ Bug Fixes to C++ Support
188188
(``[[assume(expr)]]``) creates temporary objects.
189189
- Fix the dynamic_cast to final class optimization to correctly handle
190190
casts that are guaranteed to fail (#GH137518).
191+
- Fix bug rejecting partial specialization of variable templates with auto NTTPs (#GH118190).
191192

192193
Bug Fixes to AST Handling
193194
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4083,7 +4083,6 @@ static bool CheckTemplateSpecializationScope(Sema &S, NamedDecl *Specialized,
40834083
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D);
40844084

40854085
static bool isTemplateArgumentTemplateParameter(const TemplateArgument &Arg,
4086-
NamedDecl *Param,
40874086
unsigned Depth,
40884087
unsigned Index) {
40894088
switch (Arg.getKind()) {
@@ -4123,8 +4122,9 @@ static bool isTemplateArgumentTemplateParameter(const TemplateArgument &Arg,
41234122
}
41244123

41254124
static bool isSameAsPrimaryTemplate(TemplateParameterList *Params,
4125+
TemplateParameterList *SpecParams,
41264126
ArrayRef<TemplateArgument> Args) {
4127-
if (Params->size() != Args.size())
4127+
if (Params->size() != Args.size() || Params->size() != SpecParams->size())
41284128
return false;
41294129

41304130
unsigned Depth = Params->getDepth();
@@ -4141,9 +4141,19 @@ static bool isSameAsPrimaryTemplate(TemplateParameterList *Params,
41414141
Arg = Arg.pack_begin()->getPackExpansionPattern();
41424142
}
41434143

4144-
if (!isTemplateArgumentTemplateParameter(Arg, Params->getParam(I), Depth,
4145-
I))
4144+
if (!isTemplateArgumentTemplateParameter(Arg, Depth, I))
41464145
return false;
4146+
4147+
// For NTTPs further specialization is allowed via deduced types, so
4148+
// we need to make sure to only reject here if primary template and
4149+
// specialization use the same type for the NTTP.
4150+
if (auto *SpecNTTP =
4151+
dyn_cast<NonTypeTemplateParmDecl>(SpecParams->getParam(I))) {
4152+
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(I));
4153+
if (!NTTP || NTTP->getType().getCanonicalType() !=
4154+
SpecNTTP->getType().getCanonicalType())
4155+
return false;
4156+
}
41474157
}
41484158

41494159
return true;
@@ -4341,7 +4351,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
43414351
}
43424352

43434353
if (isSameAsPrimaryTemplate(VarTemplate->getTemplateParameters(),
4344-
CTAI.CanonicalConverted) &&
4354+
TemplateParams, CTAI.CanonicalConverted) &&
43454355
(!Context.getLangOpts().CPlusPlus20 ||
43464356
!TemplateParams->hasAssociatedConstraints())) {
43474357
// C++ [temp.class.spec]p9b3:

clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,3 +621,8 @@ namespace GH73460 {
621621
int j;
622622
template struct A<int&, j, j>;
623623
} // namespace GH73460
624+
625+
namespace GH118190 {
626+
template <auto> int x;
627+
template <int i> int x<i>;
628+
}

0 commit comments

Comments
 (0)