https://github.com/a-tarasyuk created 
https://github.com/llvm/llvm-project/pull/189641

Fixes #189141

--- 

This PR prevents a crash by disallowing the use of the `selectany` attribute in 
global variable declarations.

>From 0bf941754a1c9c7717215fd961007f0c1c147cb7 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <[email protected]>
Date: Tue, 31 Mar 2026 15:00:28 +0300
Subject: [PATCH] [Clang] disallow selectany on non-global-variable
 declarations

---
 clang/docs/ReleaseNotes.rst                         |  2 ++
 clang/include/clang/Basic/Attr.td                   |  1 +
 .../pragma-attribute-supported-attributes-list.test |  1 +
 clang/test/Sema/attr-selectany.c                    |  2 +-
 clang/test/SemaCXX/attr-selectany.cpp               | 13 ++++++++++++-
 5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bbbd3a34e01d6..b963a8cb5e324 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -252,6 +252,8 @@ Attribute Changes in Clang
   sound because any writer must hold all capabilities, so holding any one
   prevents concurrent writes.
 
+- Clang now disallows use of the ``selectany`` attribute on 
non-global-variable declarations. (#GH189141)
+
 Improvements to Clang's diagnostics
 -----------------------------------
 - ``-Wunused-but-set-variable`` now diagnoses file-scope variables with
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 8d716bd05b6ab..01fa34188da84 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4477,6 +4477,7 @@ def DLLImportStaticLocal : InheritableAttr, 
TargetSpecificAttr<TargetHasDLLImpor
 
 def SelectAny : InheritableAttr {
   let Spellings = [Declspec<"selectany">, GCC<"selectany">];
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
   let Documentation = [SelectAnyDocs];
   let SimpleHandler = 1;
 }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 03b9a77ec1814..2c91b57477b44 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -201,6 +201,7 @@
 // CHECK-NEXT: SYCLSpecialClass (SubjectMatchRule_record)
 // CHECK-NEXT: ScopedLockable (SubjectMatchRule_record)
 // CHECK-NEXT: Section (SubjectMatchRule_function, 
SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, 
SubjectMatchRule_objc_property)
+// CHECK-NEXT: SelectAny (SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, 
SubjectMatchRule_objc_method)
 // CHECK-NEXT: StackProtectorIgnore (SubjectMatchRule_variable_is_local)
diff --git a/clang/test/Sema/attr-selectany.c b/clang/test/Sema/attr-selectany.c
index 1078695c26abc..dcb7376382c1a 100644
--- a/clang/test/Sema/attr-selectany.c
+++ b/clang/test/Sema/attr-selectany.c
@@ -8,4 +8,4 @@ extern __declspec(selectany) const int x1 = 1; // no warning, 
const means we nee
 // Should we really warn on this?
 extern __declspec(selectany) int x2 = 1; // expected-warning {{'extern' 
variable has an initializer}}
 
-__declspec(selectany) void foo(void) { } // expected-error{{'selectany' can 
only be applied to data items with external linkage}}
+__declspec(selectany) void foo(void) { } // expected-error{{'selectany' 
attribute only applies to global variables}}
diff --git a/clang/test/SemaCXX/attr-selectany.cpp 
b/clang/test/SemaCXX/attr-selectany.cpp
index 4afcb8130a14c..b6e9172028296 100644
--- a/clang/test/SemaCXX/attr-selectany.cpp
+++ b/clang/test/SemaCXX/attr-selectany.cpp
@@ -4,7 +4,7 @@
 
 // MSVC produces similar diagnostics.
 
-__declspec(selectany) void foo() { } // expected-error{{'selectany' can only 
be applied to data items with external linkage}}
+__declspec(selectany) void foo() { } // expected-error{{'selectany' attribute 
only applies to global variables}}
 
 __declspec(selectany) int x1 = 1;
 
@@ -53,3 +53,14 @@ extern const SomeStruct some_struct;
 
 // Without selectany, this should stay an error.
 const SomeStruct some_struct2; // expected-error {{default initialization of 
an object of const type 'const SomeStruct' without a user-provided default 
constructor}}
+
+struct __declspec(selectany) S1 {}; // expected-error {{'selectany' attribute 
only applies to global variables}}
+__declspec(selectany) struct S1 s1;
+
+void t() {
+  __declspec(selectany) int x; // expected-error {{'selectany' attribute only 
applies to global variables}}
+  __declspec(selectany) extern int y;
+}
+
+struct S2 {};
+struct __declspec(selectany) S2 s2; // expected-error {{'selectany' attribute 
only applies to global variables}}

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

Reply via email to