]> granicus.if.org Git - clang/commitdiff
A static_assert declaration cannot be a template; adding the diagnostic for this...
authorAaron Ballman <aaron@aaronballman.com>
Mon, 4 Aug 2014 20:28:35 +0000 (20:28 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Mon, 4 Aug 2014 20:28:35 +0000 (20:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214770 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDeclCXX.cpp
lib/Parse/ParseTemplate.cpp
test/Parser/cxx11-templates.cpp [new file with mode: 0644]

index ca8d25bce6ed6ce4e3c3e5d42c9ea7b42922f81f..b2b4257a5d7c93190a4df893832f93995198235d 100644 (file)
@@ -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<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 "
index 7baa6684e27d725213e57b3371d917c327dfc057..f5ce708a97ad832d0679a66318100f2d5fb0fab6 100644 (file)
@@ -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;
index fa6401f083a6001db2b9ada78acbb35c7a942605..f73b1b41bd361d16e470accada11198e9a857966 100644 (file)
@@ -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/test/Parser/cxx11-templates.cpp b/test/Parser/cxx11-templates.cpp
new file mode 100644 (file)
index 0000000..20aa9b9
--- /dev/null
@@ -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}}