https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71154

            Bug ID: 71154
           Summary: Attributes for an explicit template instantiation are
                    ignored
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: abbeyj+gcc at gmail dot com
  Target Milestone: ---

Created attachment 38501
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38501&action=edit
Reproducer

Trying to apply attributes (like visibility("default")) to an explicit template
instantiation does not work if the type has been previously mentioned in the
translation unit.

This was previously reported as part of bug #50044.  But that bug was
eventually marked as a duplicate of bug #40068 which only seems to cover the
problem with typeinfo.  The part about the problem with attributes seems to
have been lost so I'm opening this bug to cover it.

STR:
======
$ cat main.cpp
template <typename T>
class C
{
    void foo();
};

C<int> g_c_int;
C<double> g_c_double;

template <typename T>
void C<T>::foo() {}

template class __attribute__((visibility("default"))) C<int>;
template class C<double>;


$ g++ -fvisibility=hidden -fPIC -shared main.cpp -o main.so
main.cpp:13:55: warning: type attributes ignored after type is already defined
[-Wattributes]
 template class __attribute__((visibility("default"))) C<int>;
                                                       ^~~~~~


$ nm -C main.so | grep foo
000000000000061c t C<double>::foo()
0000000000000610 t C<int>::foo()

======

Note that C<int>::foo() is marked as local (lowercase t) when the intent was to
make it global (uppercase).  When compiled with clang++ instead there are no
warnings and nm reports:
0000000000000510 t C<double>::foo()
0000000000000500 W C<int>::foo()

where C<int>::foo() is global as desired.

Similar code, with the __attribute__ replaced with __declspec(dllexport), works
as expected with MSVC 2012.  That is, C<int>::foo() is exported from the DLL
and C<double>::foo() is not.


I have a patch for this which I will attach.  It just removes the relevant
checks entirely.  This seems likely to cause problems elsewhere but perhaps it
gives somebody an idea on where to start.

Reply via email to