https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90942
Bug ID: 90942 Summary: Attributes Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mail at 3v1n0 dot net Target Milestone: --- Use something like this: // Test case, wrongexport.cpp // g++ -shared -fPIC -o /tmp/libwrong.so wrongexport.cpp -fvisibility=hidden // nm -DC /tmp/libwrong.so | grep Astruct # misses AStruct<int> in gcc!!! #define EXPORT __attribute__ ((visibility ("default"))) template <typename T> struct AStruct { AStruct(T) {} }; template struct EXPORT AStruct<bool>; void ImplicitSpecializationDefinition(AStruct<int>) {} // Ignored in g++, clang++ will export it template struct EXPORT AStruct<int>; --- When compiled with clang++: - No error - Exported symbols are (as expected): 0000000000001110 W AStruct<bool>::AStruct(bool) 0000000000001110 W AStruct<bool>::AStruct(bool) 0000000000001130 W AStruct<int>::AStruct(int) 0000000000001130 W AStruct<int>::AStruct(int) When compiled with g++: - Warns: /tmp/wrongexport.cpp:17:24: warning: type attributes ignored after type is already defined [-Wattributes] template struct EXPORT AStruct<int>; ^~~~~~~~~~~~ - Exported symbols are: 000000000000059c W AStruct<bool>::AStruct(bool) 000000000000059c W AStruct<bool>::AStruct(bool) So, it's missing the symbols for AStruct<int>::AStruct(int) because the fact that is used as parameter, cause an implicit definition with default attributes. I think that in such case g++ should instead allow to define attributes at later point when those are not explicitly set. This affects mozjs https://bugzilla.mozilla.org/show_bug.cgi?id=1560064