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 <nikolasklau...@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 <nikolasklau...@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( +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits