Skip to content

Commit 3fe85ca

Browse files
authored
[clang] check constant template parameters in dependent contexts (#159463)
This patch makes sure constant template parameters are checked even in dependent contexts. This can for example diagnose narrowings earlier, but this is permitted as these templates would have no valid instantiations.
1 parent e8311f8 commit 3fe85ca

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ Improvements to Clang's diagnostics
265265
- Fixed fix-it hint for fold expressions. Clang now correctly places the suggested right
266266
parenthesis when diagnosing malformed fold expressions. (#GH151787)
267267
- Added fix-it hint for when scoped enumerations require explicit conversions for binary operations. (#GH24265)
268-
268+
- Constant template parameters are now type checked in template definitions,
269+
including template template parameters.
269270
- Fixed an issue where emitted format-signedness diagnostics were not associated with an appropriate
270271
diagnostic id. Besides being incorrect from an API standpoint, this was user visible, e.g.:
271272
"format specifies type 'unsigned int' but the argument has type 'int' [-Wformat]"

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5482,9 +5482,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
54825482
if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack())
54835483
NTTPType = NTTP->getExpansionType(ArgumentPackIndex);
54845484

5485-
if (NTTPType->isInstantiationDependentType() &&
5486-
!isa<TemplateTemplateParmDecl>(Template) &&
5487-
!Template->getDeclContext()->isDependentContext()) {
5485+
if (NTTPType->isInstantiationDependentType()) {
54885486
// Do substitution on the type of the non-type template parameter.
54895487
InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP,
54905488
CTAI.SugaredConverted,
@@ -5494,6 +5492,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
54945492

54955493
MultiLevelTemplateArgumentList MLTAL(Template, CTAI.SugaredConverted,
54965494
/*Final=*/true);
5495+
MLTAL.addOuterRetainedLevels(NTTP->getDepth());
54975496
// If the parameter is a pack expansion, expand this slice of the pack.
54985497
if (auto *PET = NTTPType->getAs<PackExpansionType>()) {
54995498
Sema::ArgPackSubstIndexRAII SubstIndex(*this, ArgumentPackIndex);

clang/test/SemaTemplate/temp_arg_template.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,8 @@ namespace CheckDependentNonTypeParamTypes {
117117
X<int, long, 3> x;
118118
}
119119
void h() {
120-
// FIXME: If we accept A<B> at all, it's not obvious what should happen
121-
// here. While parsing the template, we form
122-
// X<unsigned char, int, (unsigned char)1234>
123-
// but in the final instantiation do we get
124-
// B<unsigned char, int, (int)1234>
125-
// or
126-
// B<unsigned char, int, (int)(unsigned char)1234>
127-
// ?
128120
X<unsigned char, int, 1234> x;
129-
int check[x.value == 1234 ? 1 : -1];
121+
// expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'unsigned char'}}
130122
}
131123
};
132124

@@ -143,6 +135,20 @@ namespace CheckDependentNonTypeParamTypes {
143135
ab.g();
144136
ab.h();
145137
}
138+
139+
template<class> struct C {
140+
template<class T, T V> struct D {};
141+
using T = D<char, 1234>;
142+
// expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'char'}}
143+
};
144+
145+
template<class T> struct E {
146+
template <template <T V> class TT> struct F {
147+
using X = TT<1234>;
148+
};
149+
};
150+
// FIXME: This should be rejected, as there are no valid instantiations for E<char>::F
151+
template struct E<char>;
146152
}
147153

148154
namespace PR32185 {

0 commit comments

Comments
 (0)