Author: Sirraide Date: 2025-04-04T20:54:13+02:00 New Revision: 50f0b30cffa72129a3179bd9ac83692114f6b19f
URL: https://github.com/llvm/llvm-project/commit/50f0b30cffa72129a3179bd9ac83692114f6b19f DIFF: https://github.com/llvm/llvm-project/commit/50f0b30cffa72129a3179bd9ac83692114f6b19f.diff LOG: [Clang] [Sema] Allow static assertions in the first part of a `for` loop in C (#134415) No release note for this one because the one added by #129737 already mentions ‘non-variable declarations’. Fixes #56471. Added: clang/test/SemaCXX/for-static-assert.cpp Modified: clang/lib/Parse/ParseStmt.cpp clang/test/C/C11/n1330.c clang/test/Sema/for.c Removed: ################################################################################ diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 150b2879fc94f..e8ec140fbe3e5 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -2142,7 +2142,13 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } DeclGroupPtrTy DG; SourceLocation DeclStart = Tok.getLocation(), DeclEnd; - if (Tok.is(tok::kw_using)) { + if (!getLangOpts().CPlusPlus && + Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) { + ProhibitAttributes(attrs); + Decl *D = ParseStaticAssertDeclaration(DeclEnd); + DG = Actions.ConvertDeclToDeclGroup(D); + FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); + } else if (Tok.is(tok::kw_using)) { DG = ParseAliasDeclarationInInitStatement(DeclaratorContext::ForInit, attrs); FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation()); diff --git a/clang/test/C/C11/n1330.c b/clang/test/C/C11/n1330.c index 153f1994192dd..f8de2c1557421 100644 --- a/clang/test/C/C11/n1330.c +++ b/clang/test/C/C11/n1330.c @@ -43,14 +43,12 @@ void test(void) { _Static_assert(1, "this works"); _Static_assert(0, "this fails"); // expected-error {{static assertion failed: this fails}} - // The use of a _Static_assert in a for loop declaration is prohibited per - // 6.8.5p3 requiring the declaration to only declare identifiers for objects + // While the use of a _Static_assert in a for loop declaration is prohibited per + // 6.8.5p3 (requiring the declaration to only declare identifiers for objects // having auto or register storage class; a static assertion does not declare - // an identifier nor an object. - // FIXME: this diagnostic is pretty terrible. + // an identifier nor an object), we permit it as an extension. int i = 0; - for (_Static_assert(1, "this should not compile"); i < 10; ++i) // expected-error {{expected identifier or '('}} \ - expected-error {{expected ';' in 'for' statement specifier}} + for (_Static_assert(1, "this should compile"); i < 10; ++i) ; // Ensure that only an integer constant expression can be used as the diff --git a/clang/test/Sema/for.c b/clang/test/Sema/for.c index 33aaf7a074ad3..e16169aac0c4c 100644 --- a/clang/test/Sema/for.c +++ b/clang/test/Sema/for.c @@ -24,3 +24,8 @@ void b10(void) { for (typedef struct { int i; } (*s)(struct { int j; });;); } /* void b11 (void) { for (static _Thread_local struct { int i; } s;s.i;); } /* c11-warning {{declaration of non-local variable in 'for' loop is a C23 extension}} c23-warning {{declaration of non-local variable in 'for' loop is incompatible with C standards before C23}} */ #endif + +void b12(void) { + for(_Static_assert(1, "");;) {} /* c11-warning {{non-variable declaration in 'for' loop is a C23 extension}} + c23-warning {{non-variable declaration in 'for' loop is incompatible with C standards before C23}} */ +} diff --git a/clang/test/SemaCXX/for-static-assert.cpp b/clang/test/SemaCXX/for-static-assert.cpp new file mode 100644 index 0000000000000..f08044324e13b --- /dev/null +++ b/clang/test/SemaCXX/for-static-assert.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C permits a 'static_assert' in the first part of a 'for' loop +// whereas C++ does not. +void f() { + for(static_assert(true);;) {} // expected-error {{expected expression}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits