http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35688
--- Comment #12 from vincenzo Innocente <vincenzo.innocente at cern dot ch> 2011-11-08 08:49:22 UTC --- much better! for the test in comment 7 now I get c++ -O0 -shared -fPIC -fvisibility=hidden -o bha.so testICF.cpp nm bha.so | c++filt | grep " T " 0000000000000e5c T go() 00000000000069ce T unsigned long const& std::max<unsigned long>(unsigned long const&, unsigned long const&) 00000000000010b2 T std::__lg(long) 00000000000010d8 T operator new(unsigned long, void*) puzzled by the visibility of std::max above I modified the original test further as cat visTest.cc namespace s __attribute__((visibility("default"))) { template <class T> class vector { public: vector() { } }; template <class T> void foo(T t) { } } class A { public: A() { } s::vector<int> v; }; s::vector<A> v; int main() { A a; s::foo(a); s::foo(v); s::foo(a.v); return 0; } and I get default visibility for s::vector<int>, as expected. not necessarily as wished… In my opinion this is consistent with spec, expect bug reports though! c++ -O0 -shared -fPIC -fvisibility=hidden -o bha.so visTest.cc nm bha.so | c++filt 0000000000000d77 t __GLOBAL__sub_I_visTest.cc 0000000000000d4c t __static_initialization_and_destruction_0(int, int) 0000000000000d8c t A::A() 0000000000000dba t void s::foo<A>(A) 0000000000000dc0 t void s::foo<s::vector<A> >(s::vector<A>) 0000000000000dc6 T void s::foo<s::vector<int> >(s::vector<int>) 0000000000000db0 t s::vector<A>::vector() 0000000000000da6 T s::vector<int>::vector() 0000000000000d04 t __dyld_func_lookup 0000000000000d0a t _main 0000000000001038 d _v U dyld_stub_binder 0000000000000cf0 t dyld_stub_binding_helper p.s I verified that if "s" in NOT default visible vector<int> will become hidden