diff options
author | David Blaikie <dblaikie@gmail.com> | 2011-10-19 05:19:50 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2011-10-19 05:19:50 +0000 |
commit | 1368e58ae0eb3d92df9fa5538349b6adf6448d15 (patch) | |
tree | 3d215d41083026e2a7c114e4ba2cbc21dddb9d1b /lib/Sema/SemaTemplate.cpp | |
parent | ab795d65230c87890f99ac5c2b2f455c63099e00 (diff) |
Fix pr9789, assert-on-invalid while instantiating an (invalid) class template with a non-final parameter pack. Also improve the warning for non-final parameter packs in this scenario so it only fires once, rather than once for every template parameter after the non-final parameter pack.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142473 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 0c4e9e1eb3..00cc9b53b6 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1195,9 +1195,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, bool SawDefaultArgument = false; SourceLocation PreviousDefaultArgLoc; - bool SawParameterPack = false; - SourceLocation ParameterPackLoc; - // Dummy initialization to avoid warnings. TemplateParameterList::iterator OldParam = NewParams->end(); if (OldParams) @@ -1212,18 +1209,11 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, SourceLocation OldDefaultLoc; SourceLocation NewDefaultLoc; - // Variables used to diagnose missing default arguments + // Variable used to diagnose missing default arguments bool MissingDefaultArg = false; - // C++0x [temp.param]p11: - // If a template parameter of a primary class template or alias template - // is a template parameter pack, it shall be the last template parameter. - if (SawParameterPack && - (TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) { - Diag(ParameterPackLoc, - diag::err_template_param_pack_must_be_last_template_parameter); - Invalid = true; - } + // Variable used to diagnose non-final parameter packs + bool SawParameterPack = false; if (TemplateTypeParmDecl *NewTypeParm = dyn_cast<TemplateTypeParmDecl>(*NewParam)) { @@ -1243,7 +1233,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, assert(!NewTypeParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); SawParameterPack = true; - ParameterPackLoc = NewTypeParm->getLocation(); } else if (OldTypeParm && OldTypeParm->hasDefaultArgument() && NewTypeParm->hasDefaultArgument()) { OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc(); @@ -1288,7 +1277,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, assert(!NewNonTypeParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); SawParameterPack = true; - ParameterPackLoc = NewNonTypeParm->getLocation(); } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() && NewNonTypeParm->hasDefaultArgument()) { OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc(); @@ -1313,7 +1301,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, } else if (SawDefaultArgument) MissingDefaultArg = true; } else { - // Check the presence of a default argument here. TemplateTemplateParmDecl *NewTemplateParm = cast<TemplateTemplateParmDecl>(*NewParam); @@ -1323,6 +1310,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, continue; } + // Check the presence of a default argument here. if (NewTemplateParm->hasDefaultArgument() && DiagnoseDefaultTemplateArgument(*this, TPC, NewTemplateParm->getLocation(), @@ -1336,7 +1324,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, assert(!NewTemplateParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); SawParameterPack = true; - ParameterPackLoc = NewTemplateParm->getLocation(); } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() && NewTemplateParm->hasDefaultArgument()) { OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation(); @@ -1363,6 +1350,16 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, MissingDefaultArg = true; } + // C++0x [temp.param]p11: + // If a template parameter of a primary class template or alias template + // is a template parameter pack, it shall be the last template parameter. + if (SawParameterPack && (NewParam + 1) != NewParamEnd && + (TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) { + Diag((*NewParam)->getLocation(), + diag::err_template_param_pack_must_be_last_template_parameter); + Invalid = true; + } + if (RedundantDefaultArg) { // C++ [temp.param]p12: // A template-parameter shall not be given default arguments @@ -3047,6 +3044,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // in arguments for non-template parameter packs. if ((*Param)->isTemplateParameterPack()) { + if (!HasParameterPack) + return true; if (ArgumentPack.empty()) Converted.push_back(TemplateArgument(0, 0)); else { |