From c6eb44b321c543c5bcf28727228a0cceced57e2e Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 15 Apr 2011 00:35:57 +0000 Subject: [PATCH] C1X: implement static asserts git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129555 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticParseKinds.td | 2 ++ include/clang/Basic/TokenKinds.def | 1 + lib/Parse/ParseDecl.cpp | 6 +++++- lib/Parse/ParseDeclCXX.cpp | 18 +++++++++++++----- lib/Parse/ParseTentative.cpp | 1 + lib/Parse/Parser.cpp | 1 + test/Sema/static-assert.c | 11 +++++++++++ 7 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 test/Sema/static-assert.c diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 03067e845c..26cb8e14d6 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -241,6 +241,8 @@ def err_unexected_colon_in_nested_name_spec : Error< "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 e36803e959..0c32e699e3 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -240,6 +240,7 @@ KEYWORD(_Bool , KEYNOCXX) 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 5e6c51c1ee..ee76cc73a5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -653,7 +653,7 @@ void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { /// [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 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts, DeclEnd, attrs); break; case tok::kw_static_assert: + case tok::kw__Static_assert: ProhibitAttributes(attrs); SingleDecl = ParseStaticAssertDeclaration(DeclEnd); break; @@ -2923,6 +2924,9 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { // 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 9c0730dce9..2227018c92 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -404,13 +404,21 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, 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 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } // 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 775bc9372e..9522691b64 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -58,6 +58,7 @@ bool Parser::isCXXDeclarationStatement() { 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 c5d5ef536d..492b8f5309 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -557,6 +557,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, 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 0000000000..13d7070858 --- /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"}} +} -- 2.40.0