https://github.com/TPPPP72 updated https://github.com/llvm/llvm-project/pull/198167
>From 5c90fe214c8b017faefbabe6b3a7a9463e1e6f86 Mon Sep 17 00:00:00 2001 From: TPPPP <[email protected]> Date: Mon, 18 May 2026 13:46:11 +0800 Subject: [PATCH 1/4] [Clang] Improve __block attribute coverage for ivars and static variables --- .../clang/Basic/DiagnosticSemaKinds.td | 13 +++++++--- clang/lib/Sema/SemaDecl.cpp | 10 ++++--- clang/lib/Sema/SemaDeclObjC.cpp | 7 +++-- clang/lib/Sema/SemaObjC.cpp | 26 ++++++++++++++++--- clang/test/Sema/block-misc.c | 16 +++++++----- clang/test/Sema/block-on-objc-ivars.m | 11 -------- clang/test/Sema/block.m | 11 ++++++++ clang/test/Sema/gh183974.c | 2 +- clang/test/SemaCXX/blocks.cpp | 6 +++++ 9 files changed, 71 insertions(+), 31 deletions(-) delete mode 100644 clang/test/Sema/block-on-objc-ivars.m create mode 100644 clang/test/Sema/block.m diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d7dd20d6a45e4..c1f2dc21df15c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11379,10 +11379,15 @@ def note_carries_dependency_missing_first_decl : Note< def err_carries_dependency_param_not_function_decl : Error< "'[[carries_dependency]]' attribute only allowed on parameter in a function " "declaration or lambda">; -def err_block_on_nonlocal : Error< - "__block attribute not allowed, only allowed on local variables">; -def err_block_on_vm : Error< - "__block attribute not allowed on declaration with a variably modified type">; +def err_block_not_allowed_on : Error< + "'__block' is not allowed on %enum_select<NotAllowedBlockVarReason>{" + "%NonlocalVariable{a nonlocal variable}|" + "%StaticLocalVariable{a static local variable}|" + "%CppStaticDataMember{a C++ static data member}|" + "%ObjCInstanceVariable{an Objective-C instance variable}|" + "%RegisterVariable{a 'register' variable}|" + "%VariablyModifiedType{a declaration with a variably modified type}|" + "}0">; def err_sizeless_nonlocal : Error< "non-local variable with sizeless type %0">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4b9576479e29e..12288abb26d0d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -31,6 +31,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/DiagnosticComment.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/HLSLRuntime.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" @@ -9161,7 +9162,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { } if (isVM && NewVD->hasAttr<BlocksAttr>()) { - Diag(NewVD->getLocation(), diag::err_block_on_vm); + Diag(NewVD->getLocation(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::VariablyModifiedType; NewVD->setInvalidDecl(); return; } @@ -15795,9 +15797,9 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D, << 1 << New << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); - if (New->hasAttr<BlocksAttr>()) { - Diag(New->getLocation(), diag::err_block_on_nonlocal); - } + if (New->hasAttr<BlocksAttr>()) + Diag(New->getLocation(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::NonlocalVariable; New->deduceParmAddressSpace(Context); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 53ff818a2af53..5ceccc3777409 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" @@ -4769,7 +4770,8 @@ ParmVarDecl *SemaObjC::ActOnMethodParmDeclaration(Scope *S, SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo.ArgAttrs); SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param); if (Param->hasAttr<BlocksAttr>()) { - Diag(Param->getLocation(), diag::err_block_on_nonlocal); + Diag(Param->getLocation(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::NonlocalVariable; Param->setInvalidDecl(); } @@ -5254,7 +5256,8 @@ Decl *SemaObjC::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { SemaRef.ProcessDeclAttributes(S, New, D); if (New->hasAttr<BlocksAttr>()) - Diag(New->getLocation(), diag::err_block_on_nonlocal); + Diag(New->getLocation(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::NonlocalVariable; return New; } diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp index c351e1e2079c1..32c58bf1e6641 100644 --- a/clang/lib/Sema/SemaObjC.cpp +++ b/clang/lib/Sema/SemaObjC.cpp @@ -1711,9 +1711,29 @@ 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->getStorageClass() == SC_Register) { + Diag(AL.getLoc(), diag::err_block_not_allowed_on) << diag::NotAllowedBlockVarReason::RegisterVariable; + return; + } + + if (!VD->hasLocalStorage()) { + if (VD->isStaticLocal()) + Diag(AL.getLoc(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::StaticLocalVariable; + else if (VD->isStaticDataMember()) + Diag(AL.getLoc(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::CppStaticDataMember; + else + Diag(AL.getLoc(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::NonlocalVariable; + return; + } + } + + if (isa<ObjCIvarDecl>(D)) { + Diag(AL.getLoc(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::ObjCInstanceVariable; return; } diff --git a/clang/test/Sema/block-misc.c b/clang/test/Sema/block-misc.c index c8a34b7f3c9fd..6cea409cb684d 100644 --- a/clang/test/Sema/block-misc.c +++ b/clang/test/Sema/block-misc.c @@ -144,14 +144,14 @@ void test15(void) { foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)' to parameter of type 'long (^)()'}} } -__block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}} +__block int test16i; // expected-error {{'__block' is not allowed on a nonlocal variable}} -void test16(__block int i) { // expected-error {{__block attribute not allowed, only allowed on local variables}} +void test16(__block int i) { // expected-error {{'__block' is not allowed on a nonlocal variable}} 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}} - __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}} + extern __block double extern_var; // expected-error {{'__block' is not allowed on a nonlocal variable}} + static __block char * pch; // expected-error {{'__block' is not allowed on a static local variable}} + __block int a[size]; // expected-error {{'__block' is not allowed on a declaration with a variably modified type}} + __block int (*ap)[size]; // expected-error {{'__block' is not allowed on a declaration with a variably modified type}} } void f(); @@ -219,3 +219,7 @@ void test21(void) { const char * (^func)(void) = ^{ return __func__; }; const char * (^function)(void) = ^{ return __FUNCTION__; }; const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; }; + +void test22(void){ + register __block int x; // expected-error {{'__block' is not allowed on a 'register' variable}} +} 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/Sema/block.m b/clang/test/Sema/block.m new file mode 100644 index 0000000000000..3e828a44375af --- /dev/null +++ b/clang/test/Sema/block.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s + +@interface X { + // expected-warning@-1 {{class 'X' defined without specifying a base class}} + // expected-note@-2 {{add a super class to fix this problem}} + __block int x; // expected-error {{'__block' is not allowed on an Objective-C instance variable}} +} +@end + +@implementation X +@end diff --git a/clang/test/Sema/gh183974.c b/clang/test/Sema/gh183974.c index 642a622761f69..0e1c519c5ec90 100644 --- a/clang/test/Sema/gh183974.c +++ b/clang/test/Sema/gh183974.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s -__block int x; // expected-error {{__block attribute not allowed, only allowed on local variables}} +__block int x; // expected-error {{'__block' is not allowed on a nonlocal variable}} int x; diff --git a/clang/test/SemaCXX/blocks.cpp b/clang/test/SemaCXX/blocks.cpp index 67ac7d42f52c9..e91751ac43e7e 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' is 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 (^)()'}} } >From 234a699b7668d36b1607d2610bfc0e9f611e3fce Mon Sep 17 00:00:00 2001 From: TPPPP <[email protected]> Date: Mon, 18 May 2026 13:47:44 +0800 Subject: [PATCH 2/4] remove uncessnary header --- clang/lib/Sema/SemaDecl.cpp | 1 - clang/lib/Sema/SemaDeclObjC.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 12288abb26d0d..0059516649a86 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -31,7 +31,6 @@ #include "clang/AST/Type.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/DiagnosticComment.h" -#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/HLSLRuntime.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 5ceccc3777409..04ba528098af4 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -18,7 +18,6 @@ #include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" -#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" >From 3cbef2dc70132b3e96fddf90fd814c34ad2f54cf Mon Sep 17 00:00:00 2001 From: TPPPP <[email protected]> Date: Mon, 18 May 2026 15:46:20 +0800 Subject: [PATCH 3/4] fix ci --- clang/lib/Sema/SemaObjC.cpp | 3 ++- clang/test/{Sema/block.m => SemaObjC/block-on-ivar.m} | 0 clang/test/SemaObjC/block-on-method-param.m | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) rename clang/test/{Sema/block.m => SemaObjC/block-on-ivar.m} (100%) diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp index 32c58bf1e6641..9adba1943cf2a 100644 --- a/clang/lib/Sema/SemaObjC.cpp +++ b/clang/lib/Sema/SemaObjC.cpp @@ -1713,7 +1713,8 @@ void SemaObjC::handleBlocksAttr(Decl *D, const ParsedAttr &AL) { if (const auto *VD = dyn_cast<VarDecl>(D)) { if (VD->getStorageClass() == SC_Register) { - Diag(AL.getLoc(), diag::err_block_not_allowed_on) << diag::NotAllowedBlockVarReason::RegisterVariable; + Diag(AL.getLoc(), diag::err_block_not_allowed_on) + << diag::NotAllowedBlockVarReason::RegisterVariable; return; } diff --git a/clang/test/Sema/block.m b/clang/test/SemaObjC/block-on-ivar.m similarity index 100% rename from clang/test/Sema/block.m rename to clang/test/SemaObjC/block-on-ivar.m diff --git a/clang/test/SemaObjC/block-on-method-param.m b/clang/test/SemaObjC/block-on-method-param.m index 2ef44abc5d85a..e5cec086cc06a 100644 --- a/clang/test/SemaObjC/block-on-method-param.m +++ b/clang/test/SemaObjC/block-on-method-param.m @@ -2,10 +2,10 @@ // RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s @interface I -- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp; // expected-error {{__block attribute not allowed, only allowed on local variables}} +- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp; // expected-error {{'__block' is not allowed on a nonlocal variable}} @end @implementation I -- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp {} // expected-error {{__block attribute not allowed, only allowed on local variables}} +- (void) compileSandboxProfileAndReturnError:(__attribute__((__blocks__(byref))) id)errorp {} // expected-error {{'__block' is not allowed on a nonlocal variable}} @end >From 435f9f4afa8401488d83ebfd3ff4e15faa5c802c Mon Sep 17 00:00:00 2001 From: TPPPP <[email protected]> Date: Tue, 19 May 2026 01:02:59 +0800 Subject: [PATCH 4/4] add releasenote --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f5660f9670eae..d644da8f49c16 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -506,6 +506,8 @@ Improvements to Clang's diagnostics - Added ``-Wattribute-alias`` to diagnose type mismatches between an alias and its aliased function. (#GH195550) +- Improved ``__block`` attribute coverage for ivars, static variables and register variables. (#GH197213) + Improvements to Clang's time-trace ---------------------------------- _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
