r214770 - A static_assert declaration cannot be a template; adding the diagnostic for this instead of silently accepting and producing possibly-unexpected behavior.

Aaron Ballman aaron at aaronballman.com
Mon Aug 4 13:28:35 PDT 2014


Author: aaronballman
Date: Mon Aug  4 15:28:35 2014
New Revision: 214770

URL: http://llvm.org/viewvc/llvm-project?rev=214770&view=rev
Log:
A static_assert declaration cannot be a template; adding the diagnostic for this instead of silently accepting and producing possibly-unexpected behavior.

Added:
    cfe/trunk/test/Parser/cxx11-templates.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=214770&r1=214769&r2=214770&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Aug  4 15:28:35 2014
@@ -600,6 +600,8 @@ def warn_cxx11_right_shift_in_template_a
 def warn_cxx98_compat_two_right_angle_brackets : Warning<
   "consecutive right angle brackets are incompatible with C++98 (use '> >')">,
   InGroup<CXX98Compat>, 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 "

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=214770&r1=214769&r2=214770&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Aug  4 15:28:35 2014
@@ -2075,9 +2075,10 @@ void Parser::ParseCXXClassMemberDeclarat
     }
   }
 
-  // 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;

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=214770&r1=214769&r2=214770&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Aug  4 15:28:35 2014
@@ -166,6 +166,14 @@ Parser::ParseSingleDeclarationAfterTempl
   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,

Added: cfe/trunk/test/Parser/cxx11-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx11-templates.cpp?rev=214770&view=auto
==============================================================================
--- cfe/trunk/test/Parser/cxx11-templates.cpp (added)
+++ cfe/trunk/test/Parser/cxx11-templates.cpp Mon Aug  4 15:28:35 2014
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+struct S {
+  template <typename Ty = char>
+  static_assert(sizeof(Ty) != 1, "Not a char"); // expected-error {{a static_assert declaration cannot be a template}}
+};
+
+template <typename Ty = char>
+static_assert(sizeof(Ty) != 1, "Not a char"); // expected-error {{a static_assert declaration cannot be a template}}





More information about the cfe-commits mailing list