This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
[isolde:tmp]$ cat foo.cc template <class T> T identity(T t) { return t; } template int identity(int); template __attribute__((visibility("default"))) double identity(double); [isolde:tmp]$ /work/root.u/bin/g++ -fvisibility=hidden -c foo.cc [isolde:tmp]$ nm -m foo.o 00000024 (__TEXT,__text) private external __Z8identityIdET_S0_ 00000000 (absolute) private external __Z8identityIdET_S0_.eh 00000000 (__TEXT,__text) private external __Z8identityIiET_S0_ 00000000 (absolute) private external __Z8identityIiET_S0_.eh [isolde:tmp]$
May I remark that I would find it quite odd to have attributes for functions on a template _instantiations_? I would think that the attribute should be at either the declaration or the definition. I understand that this precludes giving different instantiations different visibility, but it would make the system somewhat less odd... W.
Tastes differ, I suppose! My own feeling is that it's unnatural, when declaring an unbounded set of functions, to have to say that either all of them or none of them get exported. I find it more likely that a dynamic library author would decide that a selected few specializations are the library's interface. However, I don't insist on that point. What I do insist on: it's wrong for the compiler to silently ignore the visibility attribute on explicit instantiations. Either it should be honored, or else it should be documented and diagnosed as an error. Silently ignoring it is a nasty trap for users.
That latter point is most certainly uncontested! :-) W.
I just ran into this quirk too. It looks like you can work around by using "#pragma GCC visibility push(default)" before the explicit instantiation and then popping afterwards. I'd greatly prefer the __attribute__ syntax because that would permit me to use one macro for porting __declspec(dllexport) constructs from windows code. Even displaying a warning or error for the ignored __attribute__ would've saved me some grief.
I just got hit with that bug and spent too much time figuring out what was wrong. Here's my code, just to show an example of real-life usage: ////////////////////////////////////////////////////////////////////////// /** * Returns the unsigned version of \a number. */ template< class T > T abs( T number ) { // This is the default implementation, using comparison to zero and unary // negation operator. if ( number < 0 ) { return -number; } return number; } // Here are some specific implementations. template<> bool WRAP_API abs( bool number ); template<> char WRAP_API abs( char number ); template<> unsigned char WRAP_API abs( unsigned char number ); template<> short WRAP_API abs( short number ); template<> unsigned short WRAP_API abs( unsigned short number ); template<> int WRAP_API abs( int number ); template<> unsigned int WRAP_API abs( unsigned int number ); template<> long WRAP_API abs( long number ); template<> unsigned long WRAP_API abs( unsigned long number ); template<> float WRAP_API abs( float number ); template<> double WRAP_API abs( double number ); ////////////////////////////////////////////////////////////////////////// Please fix this bug!
Confirmed.
Regarding macros -- I just found out about the _Pragma directive from C99, so at least you can do something like this (paraphrasing some ACE code): #define EXPORT_SINGLETON_DECLARE (SINGLETON_TYPE, CLASS, LOCK) \ _Pragma ("GCC visibility push(default)") \ template class SINGLETON_TYPE <CLASS, LOCK>; \ _Pragma ("GCC visibility pop") #define IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) extern template class SINGLETON_TYPE <CLASS, LOCK>; Then define SINGLETON_DECLARE to depending on whether you're building the lib or not. A possible issue with this is that it must come before, say, a typedef of the template type. The example below works on VS but not g++ (not that VS matters, but I'm using code that does this): typedef Singleton_T<Foo, Mutex> FOO_SINGLETON; SINGLETON_DECLARE(Singleton_T, Foo, Mutex) Instead, the SINGLETON_DECLARE needs to come before the typedef or it will get hidden visibility on g++. I'm curious as to why the typedef causes the symbols to get hidden visibility -- is that in spec, or is a bug?
*** Bug 21243 has been marked as a duplicate of this bug. ***
Subject: Bug 17470 Author: jason Date: Fri Jun 30 01:15:56 2006 New Revision: 115086 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=115086 Log: PR c++/26905 PR c++/26612 PR c++/27000 PR c++/26984 PR c++/19134 * tree.c (build_decl_stat): Don't hande #pragma visibility here. * c-common.c (c_determine_visibility): Handle it here. * c-decl.c (finish_decl): Call c_determine_visibility for functions, too. * flags.h (enum symbol_visibility): Sort from most to least visibility. * tree.h: Likewise. * varasm.c (default_assemble_visibility): Likewise. * c-common.c (handle_visibility_attribute): Complain about trying to give visibility to an already defined class, or trying to change declared visibility. Always attach the attribute. * cp/decl2.c (determine_visibility): Overhaul. (determine_visibility_from_class): Likewise. (min_vis_r, type_visibility, constrain_visibility): New fns. (constrain_visibility_for_template): Likewise. (constrain_class_visibility): Likewise. * cp/decl.c (cp_finish_decl): Call determine_visibility for function decls, too. * cp/name-lookup.c (pushtag): Call determine_visibility. * cp/decl.c (duplicate_decls): Don't copy visibility from template to specialization. * cp/pt.c (check_explicit_specialization): Likewise. (lookup_template_class, tsubst_decl): Call determine_visibility. * cp/class.c (finish_struct_1): Call constrain_class_visibility. PR c++/26905 PR c++/21675 PR c++/17470 * cp/parser.c (cp_parser_explicit_instantiation): Pass the attributes to grokdeclarator. (cp_parser_type_specifier): Allow 'enum __attribute ((...)) E'. (cp_parser_enum_specifier): Likewise. (cp_parser_elaborated_type_specifier): Apply attributes if this declares only the class. (cp_parser_class_specifier): Apply leading attributes immediately. * cp/semantics.c (begin_class_definition): Add attributes parameter, apply them to the type. * attribs.c (decl_attributes): Ignore type-in-place attributes once the type has been defined. PR c++/21581 PR c++/25915 * cp/tree.c (decl_anon_ns_mem_p): New function. * cp/cp-tree.h: Declare it. * cp/decl2.c (determine_visibility): Make anonymous namespace members static. (min_vis_r, constrain_visibility): Likewise. * cp/rtti.c (create_pseudo_type_info): Set TREE_PUBLIC on pseudo-types. * cp/decl.c (cxx_init_decl_processing): Set TREE_PUBLIC on global_namespace. * cp/name-lookup.c (push_namespace_with_attribs): Don't set TREE_PUBLIC on anonymous namespaces. Added: trunk/gcc/testsuite/g++.dg/ext/visibility/anon2.C trunk/gcc/testsuite/g++.dg/ext/visibility/class1.C trunk/gcc/testsuite/g++.dg/ext/visibility/prop1.C trunk/gcc/testsuite/g++.dg/ext/visibility/redecl1.C trunk/gcc/testsuite/g++.dg/ext/visibility/template1.C trunk/gcc/testsuite/g++.dg/ext/visibility/template2.C trunk/gcc/testsuite/g++.dg/ext/visibility/template3.C trunk/gcc/testsuite/g++.dg/ext/visibility/template4.C trunk/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C trunk/gcc/testsuite/g++.dg/ext/visibility/warn1.C trunk/gcc/testsuite/g++.dg/ext/visibility/warn2.C trunk/gcc/testsuite/g++.dg/ext/visibility/warn3.C trunk/gcc/testsuite/g++.dg/ext/visibility/warn4.C Modified: trunk/gcc/ChangeLog trunk/gcc/attribs.c trunk/gcc/c-common.c trunk/gcc/c-decl.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/class.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/decl.c trunk/gcc/cp/decl2.c trunk/gcc/cp/name-lookup.c trunk/gcc/cp/parser.c trunk/gcc/cp/pt.c trunk/gcc/cp/rtti.c trunk/gcc/cp/semantics.c trunk/gcc/cp/tree.c trunk/gcc/doc/extend.texi trunk/gcc/doc/invoke.texi trunk/gcc/flags.h trunk/gcc/testsuite/g++.dg/ext/attrib14.C trunk/gcc/testsuite/g++.dg/ext/attrib9.C trunk/gcc/testsuite/g++.dg/ext/visibility/anon1.C trunk/gcc/testsuite/g++.dg/ext/visibility/assign1.C trunk/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C trunk/gcc/testsuite/g++.dg/ext/visibility/virtual.C trunk/gcc/testsuite/g++.old-deja/g++.pt/enum5.C trunk/gcc/tree.c trunk/gcc/tree.h trunk/gcc/varasm.c
Fixed.
Subject: Bug 17470 Author: jakub Date: Mon Aug 28 12:26:41 2006 New Revision: 116505 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116505 Log: 2006-07-06 Jason Merrill <jason@redhat.com> cp/ PR c++/28279 * decl2.c (finish_static_data_member_decl): Don't assert TREE_PUBLIC. 2006-07-01 Jason Merrill <jason@redhat.com> cp/ PR c++/28215 * method.c (make_thunk): Unset DECL_USE_TEMPLATE and DECL_TEMPLATE_INFO. 2006-06-30 Jason Merrill <jason@redhat.com> objcp/ * objcp-decl.c (objcp_start_struct): Pass null attributes argument to begin_class_definition. 2006-06-29 Jason Merrill <jason@redhat.com> PR c++/26905 PR c++/26612 PR c++/27000 PR c++/26984 PR c++/19134 * tree.c (build_decl_stat): Don't hande #pragma visibility here. * c-common.c (c_determine_visibility): Handle it here. * c-decl.c (finish_decl): Call c_determine_visibility for functions, too. * flags.h (enum symbol_visibility): Sort from most to least visibility. * tree.h: Likewise. * varasm.c (default_assemble_visibility): Likewise. * c-common.c (handle_visibility_attribute): Complain about trying to give visibility to an already defined class, or trying to change declared visibility. Always attach the attribute. PR c++/26905 PR c++/21675 PR c++/17470 * attribs.c (decl_attributes): Ignore type-in-place attributes once the type has been defined. cp/ PR c++/26905 PR c++/26612 PR c++/27000 PR c++/26984 PR c++/19134 * decl2.c (determine_visibility): Overhaul. (determine_visibility_from_class): Likewise. (min_vis_r, type_visibility, constrain_visibility): New fns. (constrain_visibility_for_template): Likewise. (constrain_class_visibility): Likewise. * decl.c (cp_finish_decl): Call determine_visibility for function decls, too. * name-lookup.c (pushtag): Call determine_visibility. * decl.c (duplicate_decls): Don't copy visibility from template to specialization. * pt.c (check_explicit_specialization): Likewise. (lookup_template_class, tsubst_decl): Call determine_visibility. * class.c (finish_struct_1): Call constrain_class_visibility. PR c++/26905 PR c++/21675 PR c++/17470 * parser.c (cp_parser_explicit_instantiation): Pass the attributes to grokdeclarator. (cp_parser_type_specifier): Allow 'enum __attribute ((...)) E'. (cp_parser_enum_specifier): Likewise. (cp_parser_elaborated_type_specifier): Apply attributes if this declares only the class. (cp_parser_class_specifier): Apply leading attributes immediately. * semantics.c (begin_class_definition): Add attributes parameter, apply them to the type. PR c++/21581 PR c++/25915 * tree.c (decl_anon_ns_mem_p): New function. * cp-tree.h: Declare it. * decl2.c (determine_visibility): Make anonymous namespace members static. (min_vis_r, constrain_visibility): Likewise. * rtti.c (create_pseudo_type_info): Set TREE_PUBLIC on pseudo-types. * decl.c (cxx_init_decl_processing): Set TREE_PUBLIC on global_namespace. * name-lookup.c (push_namespace_with_attribs): Don't set TREE_PUBLIC on anonymous namespaces. Added: branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/anon1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/anon2.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/class1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/prop1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/redecl1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template2.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template3.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template4.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn2.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn3.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn4.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/template/anon2.C Modified: branches/redhat/gcc-4_1-branch/gcc/ChangeLog branches/redhat/gcc-4_1-branch/gcc/attribs.c branches/redhat/gcc-4_1-branch/gcc/c-common.c branches/redhat/gcc-4_1-branch/gcc/c-decl.c branches/redhat/gcc-4_1-branch/gcc/cp/ChangeLog branches/redhat/gcc-4_1-branch/gcc/cp/class.c branches/redhat/gcc-4_1-branch/gcc/cp/cp-tree.h branches/redhat/gcc-4_1-branch/gcc/cp/decl.c branches/redhat/gcc-4_1-branch/gcc/cp/decl2.c branches/redhat/gcc-4_1-branch/gcc/cp/method.c branches/redhat/gcc-4_1-branch/gcc/cp/name-lookup.c branches/redhat/gcc-4_1-branch/gcc/cp/parser.c branches/redhat/gcc-4_1-branch/gcc/cp/pt.c branches/redhat/gcc-4_1-branch/gcc/cp/rtti.c branches/redhat/gcc-4_1-branch/gcc/cp/semantics.c branches/redhat/gcc-4_1-branch/gcc/cp/tree.c branches/redhat/gcc-4_1-branch/gcc/doc/extend.texi branches/redhat/gcc-4_1-branch/gcc/doc/invoke.texi branches/redhat/gcc-4_1-branch/gcc/flags.h branches/redhat/gcc-4_1-branch/gcc/objcp/ChangeLog branches/redhat/gcc-4_1-branch/gcc/objcp/objcp-decl.c branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/attrib14.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/attrib9.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/assign1.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/virtual.C branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.old-deja/g++.pt/enum5.C branches/redhat/gcc-4_1-branch/gcc/tree.c branches/redhat/gcc-4_1-branch/gcc/tree.h branches/redhat/gcc-4_1-branch/gcc/varasm.c