C1X: implement static asserts
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129555 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 03067e8..26cb8e1 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -241,6 +241,8 @@
"unexpected ':' in nested name specifier">;
def err_bool_redeclaration : Error<
"redeclaration of C++ built-in type 'bool'">;
+def ext_c1x_static_assert : Extension<
+ "_Static_assert is a C1X-specific feature">;
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index e36803e..0c32e69 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -240,6 +240,7 @@
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
KEYWORD(_Imaginary , KEYALL)
+KEYWORD(_Static_assert , KEYALL)
KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5e6c51c..ee76cc7 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -653,7 +653,7 @@
/// [C++] namespace-definition
/// [C++] using-directive
/// [C++] using-declaration
-/// [C++0x] static_assert-declaration
+/// [C++0x/C1X] static_assert-declaration
/// others... [FIXME]
///
Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
@@ -688,6 +688,7 @@
DeclEnd, attrs);
break;
case tok::kw_static_assert:
+ case tok::kw__Static_assert:
ProhibitAttributes(attrs);
SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
break;
@@ -2923,6 +2924,9 @@
// typedef-name
case tok::annot_typename:
+ // static_assert-declaration
+ case tok::kw__Static_assert:
+
// GNU typeof support.
case tok::kw_typeof:
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 9c0730d..2227018 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -404,13 +404,21 @@
IsTypeName, TypenameLoc);
}
-/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
+/// ParseStaticAssertDeclaration - Parse C++0x or C1X static_assert-declaration.
///
-/// static_assert-declaration:
-/// static_assert ( constant-expression , string-literal ) ;
+/// [C++0x] static_assert-declaration:
+/// static_assert ( constant-expression , string-literal ) ;
+///
+/// [C1X] static_assert-declaration:
+/// _Static_assert ( constant-expression , string-literal ) ;
///
Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
- assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
+ assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
+ "Not a static_assert declaration");
+
+ if (Tok.is(tok::kw__Static_assert) && !getLang().C1X)
+ Diag(Tok, diag::ext_c1x_static_assert);
+
SourceLocation StaticAssertLoc = ConsumeToken();
if (Tok.isNot(tok::l_paren)) {
@@ -1426,7 +1434,7 @@
}
// static_assert-declaration
- if (Tok.is(tok::kw_static_assert)) {
+ if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
// FIXME: Check for templates
SourceLocation DeclEnd;
ParseStaticAssertDeclaration(DeclEnd);
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 775bc93..9522691 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -58,6 +58,7 @@
case tok::kw_using:
// static_assert-declaration
case tok::kw_static_assert:
+ case tok::kw__Static_assert:
return true;
// simple-declaration
default:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index c5d5ef5..492b8f5 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -557,6 +557,7 @@
case tok::kw_template:
case tok::kw_export: // As in 'export template'
case tok::kw_static_assert:
+ case tok::kw__Static_assert:
// A function definition cannot start with a these keywords.
{
SourceLocation DeclEnd;
diff --git a/test/Sema/static-assert.c b/test/Sema/static-assert.c
new file mode 100644
index 0000000..13d7070
--- /dev/null
+++ b/test/Sema/static-assert.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s
+
+_Static_assert("foo", "string is nonzero"); // expected-error {{static_assert expression is not an integral constant expression}}
+
+_Static_assert(1, "1 is nonzero");
+_Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}}
+
+void foo(void) {
+ _Static_assert(1, "1 is nonzero");
+ _Static_assert(0, "0 is nonzero"); // expected-error {{static_assert failed "0 is nonzero"}}
+}