[clang] [Clang] Allow the use of [[gnu::visibility]] with #pragma clang attribute (PR #145653)
Nikolas Klauser via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 26 04:24:17 PDT 2025
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/145653
>From 5b1e8206ef1e69a4304178f45732b3b1a4b0a59e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 25 Jun 2025 10:43:08 +0200
Subject: [PATCH 1/2] [Clang] Allow the use of [[gnu::visibility]] with #pragma
clang attribute
---
clang/include/clang/Basic/Attr.td | 1 +
clang/test/CodeGen/visibility.c | 10 ++++++++++
.../pragma-attribute-supported-attributes-list.test | 1 +
clang/test/Sema/attr-visibility.c | 6 ++++++
4 files changed, 18 insertions(+)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index f113cd2ba2fbf..7272715558bf2 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3735,6 +3735,7 @@ def Visibility : InheritableAttr {
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
let MeaningfulToClassTemplateDefinition = 1;
+ let PragmaAttributeSupport = 1;
let Documentation = [Undocumented];
}
diff --git a/clang/test/CodeGen/visibility.c b/clang/test/CodeGen/visibility.c
index ee760ec77879e..3abd70870bf92 100644
--- a/clang/test/CodeGen/visibility.c
+++ b/clang/test/CodeGen/visibility.c
@@ -72,3 +72,13 @@ __private_extern__ int test4 = 10;
// CHECK-HIDDEN-LABEL: define hidden void @test5()
__attribute__((availability(macosx,introduced=10.5,deprecated=10.6)))
__private_extern__ void test5(void) {}
+
+
+#pragma clang attribute push([[gnu::visibility("hidden")]], apply_to=function)
+
+// CHECK-DEFAULT-LABEL: define hidden void @func()
+// CHECK-PROTECTED-LABEL: define hidden void @func()
+// CHECK-HIDDEN-LABEL: define hidden void @func()
+void func(void) {}
+
+#pragma clang attribute pop
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 41d00dae3f69a..05693538252aa 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -212,6 +212,7 @@
// CHECK-NEXT: VTablePointerAuthentication (SubjectMatchRule_record)
// CHECK-NEXT: VecReturn (SubjectMatchRule_record)
// CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)
+// CHECK-NEXT: Visibility ()
// CHECK-NEXT: WarnUnused (SubjectMatchRule_record)
// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType, SubjectMatchRule_type_alias)
// CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
diff --git a/clang/test/Sema/attr-visibility.c b/clang/test/Sema/attr-visibility.c
index 4acca7a7f69a3..0497e9760c44f 100644
--- a/clang/test/Sema/attr-visibility.c
+++ b/clang/test/Sema/attr-visibility.c
@@ -25,3 +25,9 @@ typedef int __attribute__((visibility("default"))) bar; // expected-warning {{'v
int x __attribute__((type_visibility("default"))); // expected-error {{'type_visibility' attribute only applies to types and namespaces}}
int PR17105 __attribute__((visibility(hidden))); // expected-error {{'visibility' attribute requires a string}}
+
+#pragma clang attribute push([[gnu::visibility("default")]], apply_to=function)
+
+void func(void) {}
+
+#pragma clang attribute pop
>From fe2a70e1846eeafd227781060a3f47a7586331d8 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 26 Jun 2025 13:24:05 +0200
Subject: [PATCH 2/2] Address comments
---
clang/test/CodeGen/visibility.c | 20 +++++++++++---
clang/test/CodeGenCXX/visibility.cpp | 40 ++++++++++++++++++++++------
2 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/clang/test/CodeGen/visibility.c b/clang/test/CodeGen/visibility.c
index 3abd70870bf92..947bdf3d377a6 100644
--- a/clang/test/CodeGen/visibility.c
+++ b/clang/test/CodeGen/visibility.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
// CHECK-DEFAULT: @g_def ={{.*}} global i32 0
// CHECK-DEFAULT: @g_com ={{.*}} global i32 0
@@ -81,4 +81,18 @@ __private_extern__ void test5(void) {}
// CHECK-HIDDEN-LABEL: define hidden void @func()
void func(void) {}
+void call(void) {
+ implicit_function();
+ // CHECK-DEFAULT-LABEL: declare hidden i32 @implicit_function(...)
+ // CHECK-PROTECTED-LABEL: declare hidden i32 @implicit_function(...)
+ // CHECK-HIDDEN-LABEL: declare hidden i32 @implicit_function(...)
+}
+
#pragma clang attribute pop
+
+void call2(void) {
+ implicit_function2();
+ // CHECK-DEFAULT-LABEL: declare i32 @implicit_function2(...)
+ // CHECK-PROTECTED-LABEL: declare i32 @implicit_function2(...)
+ // CHECK-HIDDEN-LABEL: declare i32 @implicit_function2(...)
+}
diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp
index 442e2a5aaa2b3..3203d476c45f9 100644
--- a/clang/test/CodeGenCXX/visibility.cpp
+++ b/clang/test/CodeGenCXX/visibility.cpp
@@ -218,7 +218,7 @@ namespace test27 {
namespace Test1 {
// CHECK-LABEL: define hidden void @_ZN5Test11fEv
void HIDDEN f() { }
-
+
}
namespace Test2 {
@@ -230,7 +230,7 @@ namespace Test2 {
// CHECK-LABEL: define hidden void @_ZN5Test21A1fEv
void A::f() { }
}
-
+
namespace Test3 {
struct HIDDEN A {
struct B {
@@ -240,7 +240,7 @@ namespace Test3 {
// B is a nested class where its parent class is hidden.
// CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv
- void A::B::f() { }
+ void A::B::f() { }
}
namespace Test4 HIDDEN {
@@ -248,15 +248,15 @@ namespace Test4 HIDDEN {
// Test4::g is in a hidden namespace.
// CHECK-LABEL: define hidden void @_ZN5Test41gEv
- void g() { }
-
+ void g() { }
+
struct DEFAULT A {
void f();
};
-
+
// A has default visibility.
// CHECK-LABEL: define void @_ZN5Test41A1fEv
- void A::f() { }
+ void A::f() { }
}
namespace Test5 {
@@ -266,7 +266,7 @@ namespace Test5 {
// CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv()
void f() { }
}
-
+
namespace NS {
// g is in NS, but this NS decl is not hidden.
// CHECK-LABEL: define void @_ZN5Test52NS1gEv
@@ -1536,3 +1536,27 @@ namespace test75 {
// CHECK-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
}
+
+#pragma clang attribute push([[gnu::visibility("hidden")]], apply_to=function)
+
+namespace pragma_test {
+ struct S {
+ S();
+ };
+
+ S::S() = default;
+ // CHECK-LABEL: define hidden void @_ZN11pragma_test1SC2Ev(
+ // CHECK-HIDDEN-LABEL: define hidden void @_ZN11pragma_test1SC2Ev(
+}
+
+#pragma clang attribute pop
+
+namespace no_pragma_test {
+ struct S {
+ S();
+ };
+
+ S::S() = default;
+ // CHECK-LABEL: define void @_ZN14no_pragma_test1SC2Ev(
+ // CHECK-HIDDEN-LABEL: define hidden void @_ZN14no_pragma_test1SC2Ev(
+}
More information about the cfe-commits
mailing list