https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89156
Bug ID: 89156 Summary: Templated member function has DEFAULT visibility although instantiating class has not Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gcc at martinien dot de Target Milestone: --- My understanding is this: When a templated class should get DEFAULT visibility, the class itself and all the instantiating classes need to be marked with __attribute__((visibility("default"))). gcc and clang behave that way. However, they differ for templated member functions: gcc always exports (probably using the visibility of the containing class), but clang follows the rule above. Example: $ cat vis_test.cpp #define EXPORT __attribute__((visibility("default"))) template<int a> class ClassHidden { void func() {} }; class EXPORT ClassWithTemplateFunction { template<typename T> static void func() {} }; template<class T> class EXPORT ClassExported { void func() {} }; template class ClassHidden<1>; template void ClassWithTemplateFunction::func<ClassHidden<1>>(); template class ClassExported<ClassHidden<1>>; $ cat test.sh #!/bin/bash echo echo "gcc trunk:" /h/tools/gcctrunk/bin/g++ -fvisibility=hidden -c vis_test.cpp -o vis_test_gcc.o && readelf -sW vis_test_gcc.o | c++filt | grep --color=never Class echo echo "clang trunk:" /h/tools/llvmtrunk/bin/clang++ -fvisibility=hidden -c vis_test.cpp -o vis_test_clang.o && readelf -sW vis_test_clang.o | c++filt | grep --color=never Class $ ./test.sh gcc trunk: 14: 0000000000000000 11 FUNC WEAK HIDDEN 7 ClassHidden<1>::func() 15: 0000000000000000 7 FUNC WEAK DEFAULT 8 void ClassWithTemplateFunction::func<ClassHidden<1> >() 16: 0000000000000000 11 FUNC WEAK HIDDEN 9 ClassExported<ClassHidden<1> >::func() clang trunk: 5: 0000000000000000 10 FUNC WEAK HIDDEN 4 ClassHidden<1>::func() 6: 0000000000000000 10 FUNC WEAK HIDDEN 8 ClassExported<ClassHidden<1> >::func() 7: 0000000000000000 6 FUNC WEAK HIDDEN 6 void ClassWithTemplateFunction::func<ClassHidden<1> >() For ClassWithTemplateFunction::func<ClassHidden<1> >(), gcc emits DEFAULT visibility. Who is right, and why? :) Best regards, Martin -- www.productive-cpp.com