https://github.com/TPPPP72 created 
https://github.com/llvm/llvm-project/pull/198167

As discussed in #194856, we need to improve the diagnostic coverage for the 
`__block` attribute.

The modifications I made are as follows:
1. added diagnostic definitions
2. modified diagnostic logic
3. added test cases
4. modified the affected test cases

close #197213

>From 5115bca93c6f979f5022948ebd7179fb9db55bfa Mon Sep 17 00:00:00 2001
From: TPPPP <[email protected]>
Date: Sun, 17 May 2026 19:00:28 +0800
Subject: [PATCH] [Clang] Improve __block attribute coverage for ivars and
 static variables

---
 .../include/clang/Basic/DiagnosticSemaKinds.td  |  6 ++++++
 clang/lib/Sema/SemaObjC.cpp                     | 17 ++++++++++++++---
 clang/test/Sema/{block-misc.c => block-misc.m}  | 12 +++++++++++-
 clang/test/Sema/block-on-objc-ivars.m           | 11 -----------
 clang/test/SemaCXX/blocks.cpp                   |  6 ++++++
 5 files changed, 37 insertions(+), 15 deletions(-)
 rename clang/test/Sema/{block-misc.c => block-misc.m} (94%)
 delete mode 100644 clang/test/Sema/block-on-objc-ivars.m

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d7dd20d6a45e4..b788999f12e87 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11381,6 +11381,12 @@ def err_carries_dependency_param_not_function_decl : 
Error<
   "declaration or lambda">;
 def err_block_on_nonlocal : Error<
   "__block attribute not allowed, only allowed on local variables">;
+def err_block_on_static_local : Error<
+  "__block attribute not allowed on a static local variable">;
+def err_block_on_cxx_static_member : Error<
+  "__block attribute not allowed on a C++ static data member">;
+def err_block_on_objc_ivar : Error<
+  "__block attribute cannot be specified on an Objective-C instance variable">;
 def err_block_on_vm : Error<
   "__block attribute not allowed on declaration with a variably modified 
type">;
 def err_sizeless_nonlocal : Error<
diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp
index c351e1e2079c1..a2206baaa7d84 100644
--- a/clang/lib/Sema/SemaObjC.cpp
+++ b/clang/lib/Sema/SemaObjC.cpp
@@ -1711,9 +1711,20 @@ void SemaObjC::handleBlocksAttr(Decl *D, const 
ParsedAttr &AL) {
     return;
   }
 
-  VarDecl *VD = dyn_cast<VarDecl>(D);
-  if (VD && !VD->hasLocalStorage()) {
-    Diag(AL.getLoc(), diag::err_block_on_nonlocal) << AL;
+  if (const auto *VD = dyn_cast<VarDecl>(D)) {
+    if (!VD->hasLocalStorage()) {
+      if (VD->isStaticLocal())
+        Diag(AL.getLoc(), diag::err_block_on_static_local);
+      else if (VD->isStaticDataMember())
+        Diag(AL.getLoc(), diag::err_block_on_cxx_static_member);
+      else
+        Diag(AL.getLoc(), diag::err_block_on_nonlocal);
+      return;
+    }
+  }
+
+  if (isa<ObjCIvarDecl>(D)) {
+    Diag(AL.getLoc(), diag::err_block_on_objc_ivar);
     return;
   }
 
diff --git a/clang/test/Sema/block-misc.c b/clang/test/Sema/block-misc.m
similarity index 94%
rename from clang/test/Sema/block-misc.c
rename to clang/test/Sema/block-misc.m
index c8a34b7f3c9fd..ccef365008a47 100644
--- a/clang/test/Sema/block-misc.c
+++ b/clang/test/Sema/block-misc.m
@@ -149,7 +149,7 @@ __block int test16i;  // expected-error {{__block attribute 
not allowed, only al
 void test16(__block int i) { // expected-error {{__block attribute not 
allowed, only allowed on local variables}}
   int size = 5;
   extern __block double extern_var; // expected-error {{__block attribute not 
allowed, only allowed on local variables}}
-  static __block char * pch; // expected-error {{__block attribute not 
allowed, only allowed on local variables}}
+  static __block char * pch; // expected-error {{__block attribute not allowed 
on a static local variable}}
   __block int a[size]; // expected-error {{__block attribute not allowed on 
declaration with a variably modified type}}
   __block int (*ap)[size]; // expected-error {{__block attribute not allowed 
on declaration with a variably modified type}}
 }
@@ -219,3 +219,13 @@ void test21(void) {
 const char * (^func)(void) = ^{ return __func__; };
 const char * (^function)(void) = ^{ return __FUNCTION__; };
 const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; };
+
+@interface test22 {
+  // expected-warning@-1 {{class 'test22' defined without specifying a base 
class}}
+  // expected-note@-2 {{add a super class to fix this problem}}
+  __block int _myIvar; // expected-error {{__block attribute cannot be 
specified on an Objective-C instance variable}}
+}
+@end
+
+@implementation test22
+@end
diff --git a/clang/test/Sema/block-on-objc-ivars.m 
b/clang/test/Sema/block-on-objc-ivars.m
deleted file mode 100644
index f37dc12fc109c..0000000000000
--- a/clang/test/Sema/block-on-objc-ivars.m
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
-
-@interface MyClass {
-    // expected-warning@-1 {{class 'MyClass' defined without specifying a base 
class}}
-    // expected-note@-2 {{add a super class to fix this problem}}
-    __block int _myIvar;
-}
-@end
-
-@implementation MyClass
-@end
diff --git a/clang/test/SemaCXX/blocks.cpp b/clang/test/SemaCXX/blocks.cpp
index 67ac7d42f52c9..d572412b51c43 100644
--- a/clang/test/SemaCXX/blocks.cpp
+++ b/clang/test/SemaCXX/blocks.cpp
@@ -164,6 +164,12 @@ void static_data_member() {
   };
 }
 
+namespace test8{
+  class X{
+    __block static int x; // expected-error {{__block attribute not allowed on 
a C++ static data member}}
+  };
+}
+
 namespace gh189247 {
   template<void (^)()> struct A; // expected-error {{a non-type template 
parameter cannot have type 'void (^)()'}}
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to