llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Andrew Savonichev (asavonic) <details> <summary>Changes</summary> As reported in issue #<!-- -->103477, visibility of instantiated member functions used to be ignored when calculating visibility of a specialization. This patch modifies `getLVForClassMember` to look up for a source template for an instantiated member, and changes `mergeTemplateLV` to apply it. A similar issue was reported in #<!-- -->31462, but it seems that `extern` declaration with visibility prevents the function from being emitted as hidden. This behavior seems correct, even though GCC emits it as with default visibility instead. Both tests from #<!-- -->103477 and #<!-- -->31462 are added as LIT tests `test72` and `test73` respectively. --- Full diff: https://github.com/llvm/llvm-project/pull/136128.diff 2 Files Affected: - (modified) clang/lib/AST/Decl.cpp (+10-3) - (modified) clang/test/CodeGenCXX/visibility.cpp (+37-1) ``````````diff diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index ad1cb01592e9b..b59619892979a 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -400,9 +400,9 @@ void LinkageComputer::mergeTemplateLV( FunctionTemplateDecl *temp = specInfo->getTemplate(); // Merge information from the template declaration. LinkageInfo tempLV = getLVForDecl(temp, computation); - // The linkage of the specialization should be consistent with the - // template declaration. - LV.setLinkage(tempLV.getLinkage()); + // The linkage and visibility of the specialization should be + // consistent with the template declaration. + LV.mergeMaybeWithVisibility(tempLV, considerVisibility); // Merge information from the template parameters. LinkageInfo paramsLV = @@ -1051,6 +1051,13 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, if (const auto *redeclTemp = dyn_cast<RedeclarableTemplateDecl>(temp)) { if (isExplicitMemberSpecialization(redeclTemp)) { explicitSpecSuppressor = temp->getTemplatedDecl(); + } else if (const RedeclarableTemplateDecl *from = + redeclTemp->getInstantiatedFromMemberTemplate()) { + // If no explicit visibility is specified yet, and this is an + // instantiated member of a template, look up visibility there + // as well. + LinkageInfo fromLV = from->getLinkageAndVisibility(); + LV.mergeMaybeWithVisibility(fromLV, considerVisibility); } } } diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp index e1061f3dbd18f..b69278a71d48e 100644 --- a/clang/test/CodeGenCXX/visibility.cpp +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -1457,9 +1457,45 @@ namespace test71 { // CHECK-LABEL: declare hidden noundef i32 @_ZN6test713fooIiE3zedEv( // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIiE3barIiEET_v( // CHECK-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv( - // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIlE3barIiEET_v( + // CHECK-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v( // CHECK-HIDDEN-LABEL: declare hidden noundef i32 @_ZN6test713fooIiE3zedEv( // CHECK-HIDDEN-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIiE3barIiEET_v( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v( } + +// https://github.com/llvm/llvm-project/issues/103477 +namespace test72 { + template <class a> + struct t { + template <int> + static HIDDEN void bar() {} + }; + + void test() { + t<char>::bar<1>(); + } + // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test721tIcE3barILi1EEEvv( + // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test721tIcE3barILi1EEEvv( +} + +// https://github.com/llvm/llvm-project/issues/31462 +namespace test73 { + template <class T> struct s { + template <class U> + __attribute__((__visibility__("hidden"))) U should_not_be_exported(); + }; + + template <class T> template <class U> U s<T>::should_not_be_exported() { + return U(); + } + + extern template struct __attribute__((__visibility__("default"))) s<int>; + + int f() { + s<int> o; + return o.should_not_be_exported<int>(); + } + // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test731sIiE22should_not_be_exportedIiEET_v( + // CHECK-HIDDEN-LABEL: define linkonce_odr noundef i32 @_ZN6test731sIiE22should_not_be_exportedIiEET_v( +} `````````` </details> https://github.com/llvm/llvm-project/pull/136128 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits