Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -1803,7 +1803,7 @@ /// isForInitDeclaration - Disambiguates between a declaration or an /// expression in the context of the C 'clause-1' or the C++ // 'for-init-statement' part of a 'for' statement. - /// Returns true for declaration, false for expression. + /// Returns true for C declaration or C++ simple-declaration, false otherwise bool isForInitDeclaration() { if (getLangOpts().CPlusPlus) return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true); @@ -2275,7 +2275,8 @@ SourceLocation &DeclEnd, AccessSpecifier AS = AS_none, Decl **OwnedType = nullptr); - Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd); + Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd, + bool RequireSemi = true); Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, SourceLocation &DeclEnd); Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -684,7 +684,8 @@ /// [C11] static_assert-declaration: /// _Static_assert ( constant-expression , string-literal ) ; /// -Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ +Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd, + bool RequireSemi) { assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) && "Not a static_assert declaration"); @@ -739,7 +740,8 @@ T.consumeClose(); DeclEnd = Tok.getLocation(); - ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); + if (RequireSemi) + ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(), Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -1553,9 +1553,17 @@ ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt); SourceLocation DeclStart = Tok.getLocation(), DeclEnd; - DeclGroupPtrTy DG = ParseSimpleDeclaration( - Declarator::ForContext, DeclEnd, attrs, false, - MightBeForRangeStmt ? &ForRangeInit : nullptr); + DeclGroupPtrTy DG; + // in C11, the declaration may be a static_assert-declaration + if (Tok.is(tok::kw__Static_assert)) { + ProhibitAttributes(attrs); + DG = Actions.ConvertDeclToDeclGroup( + ParseStaticAssertDeclaration(DeclEnd, false)); + } else { + DG = ParseSimpleDeclaration( + Declarator::ForContext, DeclEnd, attrs, false, + MightBeForRangeStmt ? &ForRangeInit : nullptr); + } FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); if (ForRangeInit.ParsedForRangeDecl()) { Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus11 ? Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -1612,6 +1612,9 @@ // declare identifiers for objects having storage class 'auto' or // 'register'. for (auto *DI : DS->decls()) { + // C11: skip over static assertions + if (isa(DI)) + continue; VarDecl *VD = dyn_cast(DI); if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage()) VD = nullptr; Index: test/Parser/static-assert.c =================================================================== --- test/Parser/static-assert.c +++ test/Parser/static-assert.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify %s + +void f() { + for (_Static_assert(1, "1 is nonzero");;) {} + for (_Static_assert(0, "0 is nonzero");;) {} // expected-error {{static_assert failed "0 is nonzero"}} +} Index: test/Parser/static-assert.cpp =================================================================== --- test/Parser/static-assert.cpp +++ test/Parser/static-assert.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -xc++ -std=c++11 -fsyntax-only -verify %s + +void f() { + for (static_assert(1, "1 is nonzero");;) {} // expected-error {{expected expression}} + for (static_assert(0, "0 is nonzero");;) {} // expected-error {{expected expression}} +}