------- Comment #2 from gd at spherenet dot de 2007-06-25 23:38 ------- Here is the reduced testcase which shows the bug: ============= namespace std __attribute__((__visibility__("default"))) { template<typename _CharT> class basic_streambuf { friend void getline(); }; extern template class basic_streambuf<char>; }
class Test { void test(); }; void Test::test() { } ============== The extern declaration triggers instantiate_class_template (pt.c) before the scope of the namespace is left and its visibility popped. While handling the friend declaration, we push into the namespace's scope a second time which clears its has_visibility flag. Hence, the visibility is not popped when we finally leave the namespace. What about the following patch proposal: * cp/name-lookup.c (push_namespace_with_attribs) Do not clear the has_visibility flag when entering a namespace's scope, ... (leave_scope) ... but when leaving --- gcc-4_2-branch/gcc/cp/name-lookup.c (revision 126002) +++ gcc-4_2-branch/gcc/cp/name-lookup.c (working copy) @@ -1350,7 +1350,12 @@ #ifdef HANDLE_PRAGMA_VISIBILITY if (scope->has_visibility) - pop_visibility (); + { + pop_visibility (); + /* Clear has_visibility in case the next namespace-definition has + no visibility attribute. */ + scope->has_visibility = 0; + } #endif /* Move one nesting level up. */ @@ -3067,9 +3072,6 @@ current_namespace = d; #ifdef HANDLE_PRAGMA_VISIBILITY - /* Clear has_visibility in case a previous namespace-definition had a - visibility attribute and this one doesn't. */ - current_binding_level->has_visibility = 0; for (d = attributes; d; d = TREE_CHAIN (d)) { tree name = TREE_PURPOSE (d); -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32470