@@ -1591,8 +1591,16 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
15911591 assert(S->isTemplateParamScope() &&
15921592 "Template template parameter not in template parameter scope!");
15931593
1594- // Construct the parameter object.
15951594 bool IsParameterPack = EllipsisLoc.isValid();
1595+
1596+ bool Invalid = false;
1597+ if (CheckTemplateParameterList(
1598+ Params,
1599+ /*OldParams=*/nullptr,
1600+ IsParameterPack ? TPC_TemplateTemplateParameterPack : TPC_Other))
1601+ Invalid = true;
1602+
1603+ // Construct the parameter object.
15961604 TemplateTemplateParmDecl *Param = TemplateTemplateParmDecl::Create(
15971605 Context, Context.getTranslationUnitDecl(),
15981606 NameLoc.isInvalid() ? TmpLoc : NameLoc, Depth, Position, IsParameterPack,
@@ -1615,9 +1623,12 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
16151623 if (Params->size() == 0) {
16161624 Diag(Param->getLocation(), diag::err_template_template_parm_no_parms)
16171625 << SourceRange(Params->getLAngleLoc(), Params->getRAngleLoc());
1618- Param-> setInvalidDecl () ;
1626+ Invalid = true ;
16191627 }
16201628
1629+ if (Invalid)
1630+ Param->setInvalidDecl();
1631+
16211632 // C++0x [temp.param]p9:
16221633 // A default template-argument may be specified for any kind of
16231634 // template-parameter that is not a template parameter pack.
@@ -2066,7 +2077,7 @@ DeclResult Sema::CheckClassTemplate(
20662077 SemanticContext->isDependentContext())
20672078 ? TPC_ClassTemplateMember
20682079 : TUK == TagUseKind::Friend ? TPC_FriendClassTemplate
2069- : TPC_ClassTemplate ,
2080+ : TPC_Other ,
20702081 SkipBody))
20712082 Invalid = true;
20722083
@@ -2208,9 +2219,8 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S,
22082219 SourceLocation ParamLoc,
22092220 SourceRange DefArgRange) {
22102221 switch (TPC) {
2211- case Sema::TPC_ClassTemplate:
2212- case Sema::TPC_VarTemplate:
2213- case Sema::TPC_TypeAliasTemplate:
2222+ case Sema::TPC_Other:
2223+ case Sema::TPC_TemplateTemplateParameterPack:
22142224 return false;
22152225
22162226 case Sema::TPC_FunctionTemplate:
@@ -2383,8 +2393,11 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
23832393 MissingDefaultArg = true;
23842394 } else if (NonTypeTemplateParmDecl *NewNonTypeParm
23852395 = dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) {
2386- // Check for unexpanded parameter packs.
2387- if (!NewNonTypeParm->isParameterPack () &&
2396+ // Check for unexpanded parameter packs, except in a template template
2397+ // parameter pack, as in those any unexpanded packs should be expanded
2398+ // along with the parameter itself.
2399+ if (TPC != TPC_TemplateTemplateParameterPack &&
2400+ !NewNonTypeParm->isParameterPack() &&
23882401 DiagnoseUnexpandedParameterPack(NewNonTypeParm->getLocation(),
23892402 NewNonTypeParm->getTypeSourceInfo(),
23902403 UPPC_NonTypeTemplateParameterType)) {
@@ -2492,8 +2505,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
24922505 // If a template parameter of a primary class template or alias template
24932506 // is a template parameter pack, it shall be the last template parameter.
24942507 if (SawParameterPack && (NewParam + 1) != NewParamEnd &&
2495- (TPC == TPC_ClassTemplate || TPC == TPC_VarTemplate ||
2496- TPC == TPC_TypeAliasTemplate)) {
2508+ (TPC == TPC_Other || TPC == TPC_TemplateTemplateParameterPack)) {
24972509 Diag((*NewParam)->getLocation(),
24982510 diag::err_template_param_pack_must_be_last_template_parameter);
24992511 Invalid = true;
@@ -2526,8 +2538,8 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
25262538 << PrevModuleName;
25272539 Invalid = true;
25282540 } else if (MissingDefaultArg &&
2529- (TPC == TPC_ClassTemplate || TPC == TPC_FriendClassTemplate ||
2530- TPC == TPC_VarTemplate || TPC == TPC_TypeAliasTemplate )) {
2541+ (TPC == TPC_Other || TPC == TPC_TemplateTemplateParameterPack ||
2542+ TPC == TPC_FriendClassTemplate )) {
25312543 // C++ 23[temp.param]p14:
25322544 // If a template-parameter of a class template, variable template, or
25332545 // alias template has a default template argument, each subsequent
0 commit comments