Since handle_visibility_attribute as its very first action checks decl_function_context (decl) != 0, and since the visibility attribute of the function template does not get inherited to its static variables, there is no way to actually limit the visibility of these static variables. This in turn prevents on IA64 that the variable be accessed without going through the linkage table at all (i.e. even saving the pointless instruction resulting from the linker conversion of ltoff22x/ldxmov). Along with that, it might even lead to ill behavior since the containing function instances can't be overridden by identically named ones in a different load module, but the static variables (being weak, but not visibility restricted) can.
We need a testcase, and a suggestion for the behaviour you are expecting of GCC.
I'm sorry, test case below. The expectation would be that the visibility attribute gets inherited (as described above) from function template instances and member functions of class template instances to their static variables. If that conflicts with anything I can't think of right now, then the backup solution would be to allow the attribute on such objects. unsigned gu; template<typename T> T test() __attribute__((__visibility__("hidden"))); template<typename T> T test() { static T st; return st = gu; } void test() { test<unsigned>(); }
Mark did some work on the visibility stuff, so I'm CC'ing him. Mark, this sounds like a reasonable request to me. What do you think?
Yes, I agree that it seems logical for a static variable to have the same visibility as its containing function, independently of whether or not that containing function is a template instance.
Subject: Bug 19238 Author: jason Date: Tue Mar 21 03:19:06 2006 New Revision: 112239 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112239 Log: PR c++/21764 * c-pragma.c (visstack): Move out of handle_pragma_visibility. (push_visibility, pop_visibility): Likewise. * c-pragma.h: Declare them. * cp/name-lookup.h (struct cp_binding_level): Add has_visibility bitfield. * cp/name-lookup.c: Include c-pragma.h. (push_namespace_with_attribs): Split out from push_namespace. Push visibility if appropriate. Set TREE_PUBLIC on namespaces. (leave_scope): Pop visibility if appropriate. * cp/parser.c (cp_parser_declaration, cp_parser_namespace_name): Allow attributes on namespace declarations. PR c++/19238 * cp/decl.c (cp_finish_decl): Call determine_visibility later. (start_preparsed_function): Likewise. * cp/cp-tree.h (CP_TYPE_CONTEXT, TYPE_NAMESPACE_SCOPE_P): New macros. (TYPE_CLASS_SCOPE_P, TYPE_FUNCTION_SCOPE_P): New macros. * cp/decl2.c (determine_visibility_from_class): Split out from... (determine_visibility): ...here. Handle function scope and nested classes. (import_export_decl): Move visibility handling to determine_visibility_from_class. Added: trunk/gcc/testsuite/g++.dg/ext/visibility/local1.C trunk/gcc/testsuite/g++.dg/ext/visibility/namespace1.C Modified: trunk/gcc/ChangeLog trunk/gcc/c-pragma.c trunk/gcc/c-pragma.h trunk/gcc/cp/ChangeLog 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/name-lookup.h trunk/gcc/cp/parser.c
Fixed.