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

Reply via email to