[clang] [Clang] [Sema] Allow static assertions in the first part of a `for` loop in C (PR #134415)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 4 09:46:08 PDT 2025
https://github.com/Sirraide created https://github.com/llvm/llvm-project/pull/134415
No release note for this one because the one added by #129737 already mentions ‘non-variable declarations’.
Fixes #56471.
>From 1806f6192cc320b50b0a49a245d04bff08f348af Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Fri, 4 Apr 2025 18:42:36 +0200
Subject: [PATCH] [Clang] [Sema] Allow static assertions in the first part of a
for loop in C
---
clang/lib/Parse/ParseStmt.cpp | 8 +++++++-
clang/test/Sema/for.c | 5 +++++
clang/test/SemaCXX/for-static-assert.cpp | 7 +++++++
3 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 clang/test/SemaCXX/for-static-assert.cpp
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/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