diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 51e5973098c14..0eadc1c773597 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -241,7 +241,8 @@ Improvements to Clang's diagnostics - Fixed fix-it hint for fold expressions. Clang now correctly places the suggested right parenthesis when diagnosing malformed fold expressions. (#GH151787) - Added fix-it hint for when scoped enumerations require explicit conversions for binary operations. (#GH24265) - +- Constant template parameters are now type checked in template definitions, + including template template parameters. - Fixed an issue where emitted format-signedness diagnostics were not associated with an appropriate diagnostic id. Besides being incorrect from an API standpoint, this was user visible, e.g.: "format specifies type 'unsigned int' but the argument has type 'int' [-Wformat]" diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index d6b25c2d83613..faeba6ada0c6b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5482,9 +5482,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack()) NTTPType = NTTP->getExpansionType(ArgumentPackIndex); - if (NTTPType->isInstantiationDependentType() && - !isa(Template) && - !Template->getDeclContext()->isDependentContext()) { + if (NTTPType->isInstantiationDependentType()) { // Do substitution on the type of the non-type template parameter. InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP, CTAI.SugaredConverted, @@ -5494,6 +5492,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, MultiLevelTemplateArgumentList MLTAL(Template, CTAI.SugaredConverted, /*Final=*/true); + MLTAL.addOuterRetainedLevels(NTTP->getDepth()); // If the parameter is a pack expansion, expand this slice of the pack. if (auto *PET = NTTPType->getAs()) { Sema::ArgPackSubstIndexRAII SubstIndex(*this, ArgumentPackIndex); diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp index aa53dba652050..431e19741ece9 100644 --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -117,16 +117,8 @@ namespace CheckDependentNonTypeParamTypes { X x; } void h() { - // FIXME: If we accept A at all, it's not obvious what should happen - // here. While parsing the template, we form - // X - // but in the final instantiation do we get - // B - // or - // B - // ? X x; - int check[x.value == 1234 ? 1 : -1]; + // expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'unsigned char'}} } }; @@ -143,6 +135,20 @@ namespace CheckDependentNonTypeParamTypes { ab.g(); ab.h(); } + + template struct C { + template struct D {}; + using T = D; + // expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'char'}} + }; + + template struct E { + template