[clang] 50f0b30 - [Clang] [Sema] Allow static assertions in the first part of a `for` loop in C (#134415)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 4 11:54:17 PDT 2025
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}}
+}
More information about the cfe-commits
mailing list