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 <aeternalm...@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}}
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to