[Bug c++/77306] New: Unable to specify visibility for explicit template instantiations
abbeyj+gcc at gmail dot com
gcc-bugzilla@gcc.gnu.org
Sat Aug 20 00:57:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77306
Bug ID: 77306
Summary: Unable to specify visibility for explicit template
instantiations
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 39477
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39477&action=edit
Reproducer
This bug is being filed as a request for a more limited form of attributes than
that which was rejected in bug #71154. That bug requested any attribute be
allowed on an explicit template instantiation. This bug limits the scope to
just __attribute__((visibility)) which should hopefully be more acceptable.
The visibility attribute is somewhat different from other attributes in that it
doesn't affect the layout or semantics of the type.
Trying to apply a visibility("default") attribute to an explicit template
instantiation does not work if the type has been previously mentioned in the
translation unit.
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 relaxes the existing check to
allow attributes on a type that has already been defined as long as the
attribute is a visibility attribute.
More information about the Gcc-bugs
mailing list