From e7c544d38800e246dd675db70653a34e104d75bd Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Mon, 4 Aug 2014 20:28:35 +0000 Subject: [PATCH] A static_assert declaration cannot be a template; adding the diagnostic for this instead of silently accepting and producing possibly-unexpected behavior. llvm-svn: 214770 --- clang/include/clang/Basic/DiagnosticParseKinds.td | 2 ++ clang/lib/Parse/ParseDeclCXX.cpp | 7 ++++--- clang/lib/Parse/ParseTemplate.cpp | 8 ++++++++ clang/test/Parser/cxx11-templates.cpp | 9 +++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 clang/test/Parser/cxx11-templates.cpp diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index ca8d25b..b2b4257 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -600,6 +600,8 @@ def warn_cxx11_right_shift_in_template_arg : Warning< def warn_cxx98_compat_two_right_angle_brackets : Warning< "consecutive right angle brackets are incompatible with C++98 (use '> >')">, InGroup, DefaultIgnore; +def err_templated_invalid_declaration : Error< + "a static_assert declaration cannot be a template">; def err_multiple_template_declarators : Error< "%select{|a template declaration|an explicit template specialization|" "an explicit template instantiation}0 can " diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 7baa668..f5ce708 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2075,9 +2075,10 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } } - // static_assert-declaration - if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) { - // FIXME: Check for templates + // static_assert-declaration. A templated static_assert declaration is + // diagnosed in Parser::ParseSingleDeclarationAfterTemplate. + if (!TemplateInfo.Kind && + (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert))) { SourceLocation DeclEnd; ParseStaticAssertDeclaration(DeclEnd); return; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index fa6401f..f73b1b4 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -166,6 +166,14 @@ Parser::ParseSingleDeclarationAfterTemplate( assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && "Template information required"); + if (Tok.is(tok::kw_static_assert)) { + // A static_assert declaration may not be templated. + Diag(Tok.getLocation(), diag::err_templated_invalid_declaration) + << TemplateInfo.getSourceRange(); + // Parse the static_assert declaration to improve error recovery. + return ParseStaticAssertDeclaration(DeclEnd); + } + if (Context == Declarator::MemberContext) { // We are parsing a member template. ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo, diff --git a/clang/test/Parser/cxx11-templates.cpp b/clang/test/Parser/cxx11-templates.cpp new file mode 100644 index 0000000..20aa9b9 --- /dev/null +++ b/clang/test/Parser/cxx11-templates.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct S { + template + static_assert(sizeof(Ty) != 1, "Not a char"); // expected-error {{a static_assert declaration cannot be a template}} +}; + +template +static_assert(sizeof(Ty) != 1, "Not a char"); // expected-error {{a static_assert declaration cannot be a template}} -- 2.7.4