[clang] Revert "[Clang] disallow selectany on non-global-variable declarations" (PR #196511)
Oleksandr Tarasiuk via cfe-commits
cfe-commits at lists.llvm.org
Fri May 8 04:13:49 PDT 2026
https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/196511
Reverts llvm/llvm-project#189641
>From c9420736d95612fd27a80930950776c824d0fcd8 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Fri, 8 May 2026 14:13:31 +0300
Subject: [PATCH] Revert "[Clang] disallow selectany on non-global-variable
declarations (#189641)"
This reverts commit 3c3e7e0784befd7b80a7fe265a3e4eb7e7e12d2f.
---
clang/docs/ReleaseNotes.rst | 1 -
clang/include/clang/Basic/Attr.td | 2 --
.../clang/Basic/DiagnosticSemaKinds.td | 4 +--
clang/lib/Sema/SemaDecl.cpp | 30 +++++++++---------
...a-attribute-supported-attributes-list.test | 1 -
clang/test/Sema/attr-selectany.c | 6 +---
clang/test/SemaCXX/attr-selectany.cpp | 31 +++++--------------
clang/test/SemaCXX/declspec-selectany.cpp | 4 +--
8 files changed, 26 insertions(+), 53 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ac462e3bf4732..40e7605e0a596 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -356,7 +356,6 @@ Attribute Changes in Clang
usage.
- Clang now allows GNU attributes between a member declarator and bit-field width. (#GH184954)
-- Clang now disallows use of the ``selectany`` attribute on non-global-variable declarations. (#GH189141)
Improvements to Clang's diagnostics
-----------------------------------
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index ffa6a17f51362..70b5773f95b08 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4510,8 +4510,6 @@ def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImpor
def SelectAny : InheritableAttr {
let Spellings = [Declspec<"selectany">, GCC<"selectany">];
- let Subjects = SubjectList<[NonParmVar], ErrorDiag,
- "variable declarations with external linkage">;
let Documentation = [SelectAnyDocs];
let SimpleHandler = 1;
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c69b2ce3648f8..c15a9ec1ff0f6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3904,8 +3904,8 @@ def warn_cmse_nonsecure_union : Warning<
InGroup<DiagGroup<"cmse-union-leak">>;
def err_attribute_weak_static : Error<
"weak declaration cannot have internal linkage">;
-def err_attribute_selectany_non_extern_var : Error<
- "'selectany' can only be applied to variables with external linkage">;
+def err_attribute_selectany_non_extern_data : Error<
+ "'selectany' can only be applied to data items with external linkage">;
def warn_attribute_hybrid_patchable_non_extern : Warning<
"'hybrid_patchable' is ignored on functions without external linkage">,
InGroup<IgnoredAttributes>;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index be9654078940f..eb5b6d65b4d58 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3140,16 +3140,15 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
--E;
continue;
}
- } else if (isa<SelectAnyAttr>(NewAttribute)) {
+ } else if (isa<SelectAnyAttr>(NewAttribute) &&
+ cast<VarDecl>(New)->isInline() &&
+ !cast<VarDecl>(New)->isInlineSpecified()) {
// Don't warn about applying selectany to implicitly inline variables.
// Older compilers and language modes would require the use of selectany
// to make such variables inline, and it would have no effect if we
// honored it.
- if (const auto *VD = dyn_cast<VarDecl>(New);
- VD && VD->isInline() && !VD->isInlineSpecified()) {
- ++I;
- continue;
- }
+ ++I;
+ continue;
} else if (isa<OMPDeclareVariantAttr>(NewAttribute)) {
// We allow to add OMP[Begin]DeclareVariantAttr to be added to
// declarations after definitions.
@@ -7120,16 +7119,15 @@ static void checkAliasAttr(Sema &S, NamedDecl &ND) {
}
static void checkSelectAnyAttr(Sema &S, NamedDecl &ND) {
- SelectAnyAttr *Attr = ND.getAttr<SelectAnyAttr>();
- if (!Attr)
- return;
-
- if (const auto *VD = dyn_cast<VarDecl>(&ND);
- VD && !VD->isStaticDataMember() && VD->isExternallyVisible())
- return;
-
- S.Diag(Attr->getLocation(), diag::err_attribute_selectany_non_extern_var);
- ND.dropAttr<SelectAnyAttr>();
+ // 'selectany' only applies to externally visible variable declarations.
+ // It does not apply to functions.
+ if (SelectAnyAttr *Attr = ND.getAttr<SelectAnyAttr>()) {
+ if (isa<FunctionDecl>(ND) || !ND.isExternallyVisible()) {
+ S.Diag(Attr->getLocation(),
+ diag::err_attribute_selectany_non_extern_data);
+ ND.dropAttr<SelectAnyAttr>();
+ }
+ }
}
static void checkHybridPatchableAttr(Sema &S, NamedDecl &ND) {
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index a5f157c18c57d..03b9a77ec1814 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -201,7 +201,6 @@
// 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_not_is_parameter)
// 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 d8a0baf4edc0b..1078695c26abc 100644
--- a/clang/test/Sema/attr-selectany.c
+++ b/clang/test/Sema/attr-selectany.c
@@ -8,8 +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 x3(void) { } // expected-error {{'selectany' attribute only applies to variable declarations with external linkage}}
-
-void t() {
- __declspec(selectany) extern int i;
-}
+__declspec(selectany) void foo(void) { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
diff --git a/clang/test/SemaCXX/attr-selectany.cpp b/clang/test/SemaCXX/attr-selectany.cpp
index 70f40618af8f3..4afcb8130a14c 100644
--- a/clang/test/SemaCXX/attr-selectany.cpp
+++ b/clang/test/SemaCXX/attr-selectany.cpp
@@ -1,14 +1,14 @@
-// RUN: %clang_cc1 -triple x86_64-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify=expected -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -fms-compatibility -fms-extensions -fsyntax-only -verify=expected -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-win32-macho -fms-compatibility -fms-extensions -fsyntax-only -verify=expected,win23-macho -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-win32-macho -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s
// MSVC produces similar diagnostics.
-__declspec(selectany) void foo() { } // expected-error{{'selectany' attribute only applies to variable declarations with external linkage}}
+__declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
__declspec(selectany) int x1 = 1;
-const __declspec(selectany) int x2 = 2; // expected-error{{'selectany' can only be applied to variables with external linkage}}
+const __declspec(selectany) int x2 = 2; // expected-error{{'selectany' can only be applied to data items with external linkage}}
extern const __declspec(selectany) int x3 = 3;
@@ -18,7 +18,7 @@ const __declspec(selectany) int x4 = 4;
// MSDN says this is incorrect, but MSVC doesn't diagnose it.
extern __declspec(selectany) int x5;
-static __declspec(selectany) int x6 = 2; // expected-error{{'selectany' can only be applied to variables with external linkage}}
+static __declspec(selectany) int x6 = 2; // expected-error{{'selectany' can only be applied to data items with external linkage}}
// FIXME: MSVC accepts this and makes x7 externally visible and comdat, but keep
// it as internal and not weak/linkonce.
@@ -36,7 +36,7 @@ class X {
__declspec(selectany) X x(1);
namespace { class Internal {}; }
-__declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to variables with external linkage}}
+__declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}}
// The D3D11 headers do something like this. MSVC doesn't error on this at
@@ -53,20 +53,3 @@ 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 variable declarations with external linkage}}
-__declspec(selectany) struct S1 s1;
-
-void t() {
- __declspec(selectany) int a; // expected-error {{'selectany' can only be applied to variables with external linkage}}
- __declspec(selectany) extern int b;
- __declspec(selectany) static int c; // expected-error {{'selectany' can only be applied to variables with external linkage}}
- __declspec(selectany) thread_local int d; // expected-error {{'selectany' can only be applied to variables with external linkage}} win23-macho-error {{thread-local storage is not supported for the current target}}
-}
-
-struct S2 {};
-struct __declspec(selectany) S2 s2; // expected-error {{'selectany' attribute only applies to variable declarations with external linkage}}
-
-struct S3 {
- __declspec(selectany) static int a; // expected-error {{'selectany' can only be applied to variables with external linkage}}
-};
diff --git a/clang/test/SemaCXX/declspec-selectany.cpp b/clang/test/SemaCXX/declspec-selectany.cpp
index 9e9c906caa008..7e64a2924c99a 100644
--- a/clang/test/SemaCXX/declspec-selectany.cpp
+++ b/clang/test/SemaCXX/declspec-selectany.cpp
@@ -3,7 +3,7 @@
// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-scei-ps4 -fdeclspec -verify
// MSVC emits this error too.
-const int __declspec(selectany) test1 = 0; // expected-error {{'selectany' can only be applied to variables with external linkage}}
+const int __declspec(selectany) test1 = 0; // expected-error {{'selectany' can only be applied to data items with external linkage}}
extern const int test2;
const int test2 = 42; // expected-note {{previous definition is here}}
@@ -15,4 +15,4 @@ const int __declspec(selectany) test3 = 42; // Standard usage.
struct Test4 {
static constexpr int sdm = 0;
};
-__declspec(selectany) constexpr int Test4::sdm; // expected-error {{'selectany' can only be applied to variables with external linkage}}
+__declspec(selectany) constexpr int Test4::sdm; // no warning
More information about the cfe-commits
mailing list