Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 96372 Details for
Bug 146817
patches for gcc-4.1.1 to fix visibility-related bugs
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
first patch
99-visibility01.patch (text/plain), 17.87 KB, created by
Jan Jitse Venselaar
on 2006-09-08 03:08:44 UTC
(
hide
)
Description:
first patch
Filename:
MIME Type:
Creator:
Jan Jitse Venselaar
Created:
2006-09-08 03:08:44 UTC
Size:
17.87 KB
patch
obsolete
>Index: gcc/testsuite/g++.dg/ext/visibility/local1.C >=================================================================== >--- gcc/testsuite/g++.dg/ext/visibility/local1.C (revision 0) >+++ gcc/testsuite/g++.dg/ext/visibility/local1.C (revision 116504) >@@ -0,0 +1,25 @@ >+// PR c++/19238 >+// Test that hidden visibility on an inline function is inherited by static >+// local variables and local classes. >+ >+// { dg-require-visibility "" } >+// { dg-final { scan-hidden "_Z1fv" } } >+// { dg-final { scan-hidden "_ZZ1fvE1i" } } >+// { dg-final { scan-hidden "_ZZ1fvEN1A1fEv" } } >+ >+__attribute ((visibility ("hidden"))) inline int >+f() >+{ >+ static int i = 2; >+ struct A >+ { >+ void f () { } >+ } a; >+ a.f(); >+ return i; >+} >+ >+int main() >+{ >+ f(); >+} >Index: gcc/testsuite/g++.dg/ext/visibility/namespace1.C >=================================================================== >--- gcc/testsuite/g++.dg/ext/visibility/namespace1.C (revision 0) >+++ gcc/testsuite/g++.dg/ext/visibility/namespace1.C (revision 116504) >@@ -0,0 +1,30 @@ >+// PR c++/21764 >+// Test for namespace visibility attribute semantics. >+ >+// { dg-require-visibility "" } >+// { dg-final { scan-hidden "_ZN3foo1fEv" } } >+// { dg-final { scan-hidden "_ZN3foo1gEv" } } >+// { dg-final { scan-hidden "_ZN3foo1A1mEv" } } >+// { dg-final { scan-hidden "_ZN3foo1tIiEEvv" } } >+// { dg-final { scan-not-hidden "_ZN3foo1hEv" } } >+ >+namespace foo __attribute ((visibility ("hidden"))) >+{ >+ int f() { } >+ void g(); >+ template <typename T> void t() { } >+ class A >+ { >+ void m (); >+ }; >+} >+ >+namespace foo >+{ >+ void h() {} >+} >+ >+void foo::g() { t<int> (); } >+ >+void foo::A::m() { } >+ >Index: gcc/cp/decl.c >=================================================================== >--- gcc/cp/decl.c (revision 116503) >+++ gcc/cp/decl.c (revision 116504) >@@ -5243,9 +5243,6 @@ > the class specifier. */ > if (!DECL_EXTERNAL (decl)) > var_definition_p = true; >- /* The variable is being defined, so determine its >- visibility. */ >- determine_visibility (decl); > } > /* If the variable has an array type, lay out the type, even if > there is no initializer. It is valid to index through the >@@ -5310,6 +5307,10 @@ > initialize_local_var (decl, init); > } > >+ /* The variable is being defined, so determine its visibility. >+ This needs to happen after the linkage is set. */ >+ determine_visibility (decl); >+ > /* If a variable is defined, and then a subsequent > definition with external linkage is encountered, we will > get here twice for the same variable. We want to avoid >@@ -10497,12 +10498,6 @@ > maybe_apply_pragma_weak (decl1); > } > >- /* Determine the ELF visibility attribute for the function. We must >- not do this before calling "pushdecl", as we must allow >- "duplicate_decls" to merge any attributes appropriately. */ >- if (!DECL_CLONED_FUNCTION_P (decl1)) >- determine_visibility (decl1); >- > /* Reset these in case the call to pushdecl changed them. */ > current_function_decl = decl1; > cfun->decl = decl1; >@@ -10621,6 +10616,13 @@ > DECL_INTERFACE_KNOWN (decl1) = 1; > } > >+ /* Determine the ELF visibility attribute for the function. We must not >+ do this before calling "pushdecl", as we must allow "duplicate_decls" >+ to merge any attributes appropriately. We also need to wait until >+ linkage is set. */ >+ if (!DECL_CLONED_FUNCTION_P (decl1)) >+ determine_visibility (decl1); >+ > begin_scope (sk_function_parms, decl1); > > ++function_depth; >Index: gcc/cp/cp-tree.h >=================================================================== >--- gcc/cp/cp-tree.h (revision 116503) >+++ gcc/cp/cp-tree.h (revision 116504) >@@ -1966,6 +1966,8 @@ > /* NULL_TREE in DECL_CONTEXT represents the global namespace. */ > #define CP_DECL_CONTEXT(NODE) \ > (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) >+#define CP_TYPE_CONTEXT(NODE) \ >+ (TYPE_CONTEXT (NODE) ? TYPE_CONTEXT (NODE) : global_namespace) > #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) > > /* 1 iff NODE has namespace scope, including the global namespace. */ >@@ -1973,15 +1975,25 @@ > (!DECL_TEMPLATE_PARM_P (NODE) \ > && TREE_CODE (CP_DECL_CONTEXT (NODE)) == NAMESPACE_DECL) > >+#define TYPE_NAMESPACE_SCOPE_P(NODE) \ >+ (TREE_CODE (CP_TYPE_CONTEXT (NODE)) == NAMESPACE_DECL) >+ > /* 1 iff NODE is a class member. */ > #define DECL_CLASS_SCOPE_P(NODE) \ > (DECL_CONTEXT (NODE) && TYPE_P (DECL_CONTEXT (NODE))) > >+#define TYPE_CLASS_SCOPE_P(NODE) \ >+ (TYPE_CONTEXT (NODE) && TYPE_P (TYPE_CONTEXT (NODE))) >+ > /* 1 iff NODE is function-local. */ > #define DECL_FUNCTION_SCOPE_P(NODE) \ > (DECL_CONTEXT (NODE) \ > && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL) > >+#define TYPE_FUNCTION_SCOPE_P(NODE) \ >+ (TYPE_CONTEXT (NODE) \ >+ && TREE_CODE (TYPE_CONTEXT (NODE)) == FUNCTION_DECL) >+ > /* 1 iff VAR_DECL node NODE is a type-info decl. This flag is set for > both the primary typeinfo object and the associated NTBS name. */ > #define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)) >Index: gcc/cp/name-lookup.c >=================================================================== >--- gcc/cp/name-lookup.c (revision 116503) >+++ gcc/cp/name-lookup.c (revision 116504) >@@ -31,6 +31,7 @@ > #include "toplev.h" > #include "diagnostic.h" > #include "debug.h" >+#include "c-pragma.h" > > /* The bindings for a particular name in a particular scope. */ > >@@ -1344,11 +1345,16 @@ > is_class_level = 0; > } > >+#ifdef HANDLE_PRAGMA_VISIBILITY >+ if (scope->has_visibility) >+ pop_visibility (); >+#endif >+ > /* Move one nesting level up. */ > current_binding_level = scope->level_chain; > > /* Namespace-scopes are left most probably temporarily, not >- completely; they can be reopen later, e.g. in namespace-extension >+ completely; they can be reopened later, e.g. in namespace-extension > or any name binding activity that requires us to resume a > namespace. For classes, we cache some binding levels. For other > scopes, we just make the structure available for reuse. */ >@@ -2971,6 +2977,15 @@ > void > push_namespace (tree name) > { >+ push_namespace_with_attribs (name, NULL_TREE); >+} >+ >+/* Same, but specify attributes to apply to the namespace. The attributes >+ only apply to the current namespace-body, not to any later extensions. */ >+ >+void >+push_namespace_with_attribs (tree name, tree attributes) >+{ > tree d = NULL_TREE; > int need_new = 1; > int implicit_use = 0; >@@ -3017,6 +3032,7 @@ > /* Make a new namespace, binding the name to it. */ > d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); > DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace); >+ TREE_PUBLIC (d) = 1; > pushdecl (d); > if (anon) > { >@@ -3034,6 +3050,36 @@ > /* Enter the name space. */ > 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); >+ tree args = TREE_VALUE (d); >+ tree x; >+ >+ if (! is_attribute_p ("visibility", name)) >+ { >+ warning (OPT_Wattributes, "%qs attribute directive ignored", >+ IDENTIFIER_POINTER (name)); >+ continue; >+ } >+ >+ x = args ? TREE_VALUE (args) : NULL_TREE; >+ if (x == NULL_TREE || TREE_CODE (x) != STRING_CST) >+ { >+ warning (OPT_Wattributes, "%qs attribute requires an NTBS argument", >+ IDENTIFIER_POINTER (name)); >+ continue; >+ } >+ >+ current_binding_level->has_visibility = 1; >+ push_visibility (TREE_STRING_POINTER (x)); >+ } >+#endif >+ > timevar_pop (TV_NAME_LOOKUP); > } > >Index: gcc/cp/decl2.c >=================================================================== >--- gcc/cp/decl2.c (revision 116503) >+++ gcc/cp/decl2.c (revision 116504) >@@ -82,6 +82,7 @@ > static void write_out_vars (tree); > static void import_export_class (tree); > static tree get_guard_bits (tree); >+static void determine_visibility_from_class (tree, tree); > > /* A list of static class variables. This is needed, because a > static class variable can be declared inside the class without >@@ -1578,13 +1579,27 @@ > } > > /* Like c_determine_visibility, but with additional C++-specific >- behavior. */ >+ behavior. > >+ Function-scope entities can rely on the function's visibility because >+ it is set in start_preparsed_function. >+ >+ Class-scope entities cannot rely on the class's visibility until the end >+ of the enclosing class definition. >+ >+ Note that because namespaces have multiple independent definitions, >+ namespace visibility is handled elsewhere using the #pragma visibility >+ machinery rather than by decorating the namespace declaration. */ >+ > void > determine_visibility (tree decl) > { > tree class_type; > >+ /* Only relevant for names with external linkage. */ >+ if (!TREE_PUBLIC (decl)) >+ return; >+ > /* Cloned constructors and destructors get the same visibility as > the underlying function. That should be set up in > maybe_clone_body. */ >@@ -1608,6 +1623,14 @@ > so they are automatically handled above. */ > gcc_assert (TREE_CODE (decl) != VAR_DECL > || !DECL_VTABLE_OR_VTT_P (decl)); >+ >+ if (DECL_FUNCTION_SCOPE_P (decl)) >+ { >+ tree fn = DECL_CONTEXT (decl); >+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn); >+ DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn); >+ } >+ > /* Entities not associated with any class just get the > visibility specified by their attributes. */ > return; >@@ -1617,34 +1640,63 @@ > the visibility of their containing class. */ > if (class_type) > { >- if (TARGET_DLLIMPORT_DECL_ATTRIBUTES >- && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type))) >+ determine_visibility_from_class (decl, class_type); >+ >+ /* Give the target a chance to override the visibility associated >+ with DECL. */ >+ if (TREE_CODE (decl) == VAR_DECL >+ && (DECL_TINFO_P (decl) >+ || (DECL_VTABLE_OR_VTT_P (decl) >+ /* Construction virtual tables are not exported because >+ they cannot be referred to from other object files; >+ their name is not standardized by the ABI. */ >+ && !DECL_CONSTRUCTION_VTABLE_P (decl))) >+ && TREE_PUBLIC (decl) >+ && !DECL_REALLY_EXTERN (decl) >+ && DECL_VISIBILITY_SPECIFIED (decl) >+ && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))) >+ targetm.cxx.determine_class_data_visibility (decl); >+ } >+} >+ >+static void >+determine_visibility_from_class (tree decl, tree class_type) >+{ >+ if (TARGET_DLLIMPORT_DECL_ATTRIBUTES >+ && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type))) >+ { >+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; >+ DECL_VISIBILITY_SPECIFIED (decl) = 1; >+ } >+ else if (TREE_CODE (decl) == FUNCTION_DECL >+ && DECL_DECLARED_INLINE_P (decl) >+ && visibility_options.inlines_hidden) >+ { >+ /* Don't change it if it has been set explicitly by user. */ >+ if (!DECL_VISIBILITY_SPECIFIED (decl)) > { >- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; >+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; > DECL_VISIBILITY_SPECIFIED (decl) = 1; > } >- else if (TREE_CODE (decl) == FUNCTION_DECL >- && DECL_DECLARED_INLINE_P (decl) >- && visibility_options.inlines_hidden) >- { >- /* Don't change it if it has been set explicitly by user. */ >- if (!DECL_VISIBILITY_SPECIFIED (decl)) >- { >- DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; >- DECL_VISIBILITY_SPECIFIED (decl) = 1; >- } >- } >- else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type)) >- { >- DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); >- DECL_VISIBILITY_SPECIFIED (decl) = 1; >- } >- else if (!DECL_VISIBILITY_SPECIFIED (decl)) >- { >- DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); >- DECL_VISIBILITY_SPECIFIED (decl) = 0; >- } > } >+ else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type)) >+ { >+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); >+ DECL_VISIBILITY_SPECIFIED (decl) = 1; >+ } >+ else if (TYPE_CLASS_SCOPE_P (class_type)) >+ determine_visibility_from_class (decl, TYPE_CONTEXT (class_type)); >+ else if (TYPE_FUNCTION_SCOPE_P (class_type)) >+ { >+ tree fn = TYPE_CONTEXT (class_type); >+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn); >+ DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn); >+ } >+ else if (!DECL_VISIBILITY_SPECIFIED (decl)) >+ { >+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); >+ DECL_VISIBILITY_SPECIFIED (decl) = 0; >+ } > } > > /* DECL is a FUNCTION_DECL or VAR_DECL. If the object file linkage >@@ -1911,21 +1963,6 @@ > comdat_linkage (decl); > } > >- /* Give the target a chance to override the visibility associated >- with DECL. */ >- if (TREE_CODE (decl) == VAR_DECL >- && (DECL_TINFO_P (decl) >- || (DECL_VTABLE_OR_VTT_P (decl) >- /* Construction virtual tables are not exported because >- they cannot be referred to from other object files; >- their name is not standardized by the ABI. */ >- && !DECL_CONSTRUCTION_VTABLE_P (decl))) >- && TREE_PUBLIC (decl) >- && !DECL_REALLY_EXTERN (decl) >- && DECL_VISIBILITY_SPECIFIED (decl) >- && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))) >- targetm.cxx.determine_class_data_visibility (decl); >- > DECL_INTERFACE_KNOWN (decl) = 1; > } > >Index: gcc/cp/name-lookup.h >=================================================================== >--- gcc/cp/name-lookup.h (revision 116503) >+++ gcc/cp/name-lookup.h (revision 116504) >@@ -259,7 +259,11 @@ > unsigned more_cleanups_ok : 1; > unsigned have_cleanups : 1; > >- /* 22 bits left to fill a 32-bit word. */ >+ /* Nonzero if this level has associated visibility which we should pop >+ when leaving the scope. */ >+ unsigned has_visibility : 1; >+ >+ /* 23 bits left to fill a 32-bit word. */ > }; > > /* The binding level currently in effect. */ >@@ -307,6 +311,7 @@ > extern void push_binding_level (struct cp_binding_level *); > > extern void push_namespace (tree); >+extern void push_namespace_with_attribs (tree, tree); > extern void pop_namespace (void); > extern void push_nested_namespace (tree); > extern void pop_nested_namespace (tree); >Index: gcc/cp/parser.c >=================================================================== >--- gcc/cp/parser.c (revision 116503) >+++ gcc/cp/parser.c (revision 116504) >@@ -7112,7 +7112,7 @@ > && (/* A named namespace definition. */ > (token2.type == CPP_NAME > && (cp_lexer_peek_nth_token (parser->lexer, 3)->type >- == CPP_OPEN_BRACE)) >+ != CPP_EQ)) > /* An unnamed namespace definition. */ > || token2.type == CPP_OPEN_BRACE)) > cp_parser_namespace_definition (parser); >@@ -10471,7 +10471,7 @@ > static void > cp_parser_namespace_definition (cp_parser* parser) > { >- tree identifier; >+ tree identifier, attribs; > > /* Look for the `namespace' keyword. */ > cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'"); >@@ -10485,10 +10485,13 @@ > else > identifier = NULL_TREE; > >+ /* Parse any specified attributes. */ >+ attribs = cp_parser_attributes_opt (parser); >+ > /* Look for the `{' to start the namespace. */ > cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"); > /* Start the namespace. */ >- push_namespace (identifier); >+ push_namespace_with_attribs (identifier, attribs); > /* Parse the body of the namespace. */ > cp_parser_namespace_body (parser); > /* Finish the namespace. */ >Index: gcc/c-pragma.c >=================================================================== >--- gcc/c-pragma.c (revision 116503) >+++ gcc/c-pragma.c (revision 116504) >@@ -596,9 +596,42 @@ > typedef enum symbol_visibility visibility; > DEF_VEC_I (visibility); > DEF_VEC_ALLOC_I (visibility, heap); >+static VEC (visibility, heap) *visstack; > >+/* Push the visibility indicated by STR onto the top of the #pragma >+ visibility stack. */ >+ >+void >+push_visibility (const char *str) >+{ >+ VEC_safe_push (visibility, heap, visstack, >+ default_visibility); >+ if (!strcmp (str, "default")) >+ default_visibility = VISIBILITY_DEFAULT; >+ else if (!strcmp (str, "internal")) >+ default_visibility = VISIBILITY_INTERNAL; >+ else if (!strcmp (str, "hidden")) >+ default_visibility = VISIBILITY_HIDDEN; >+ else if (!strcmp (str, "protected")) >+ default_visibility = VISIBILITY_PROTECTED; >+ else >+ GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected"); >+ visibility_options.inpragma = 1; >+} >+ >+/* Pop a level of the #pragma visibility stack. */ >+ >+void >+pop_visibility (void) >+{ >+ default_visibility = VEC_pop (visibility, visstack); >+ visibility_options.inpragma >+ = VEC_length (visibility, visstack) != 0; >+} >+ > /* Sets the default visibility for symbols to something other than that > specified on the command line. */ >+ > static void > handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED) > { >@@ -606,7 +639,6 @@ > tree x; > enum cpp_ttype token; > enum { bad, push, pop } action = bad; >- static VEC (visibility, heap) *visstack; > > token = pragma_lex (&x); > if (token == CPP_NAME) >@@ -624,15 +656,9 @@ > if (pop == action) > { > if (!VEC_length (visibility, visstack)) >- { >- GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>"); >- } >+ GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>"); > else >- { >- default_visibility = VEC_pop (visibility, visstack); >- visibility_options.inpragma >- = VEC_length (visibility, visstack) != 0; >- } >+ pop_visibility (); > } > else > { >Index: gcc/c-pragma.h >=================================================================== >--- gcc/c-pragma.h (revision 116503) >+++ gcc/c-pragma.h (revision 116504) >@@ -75,6 +75,8 @@ > visibility is not supported on the host OS platform the > statements are ignored. */ > #define HANDLE_PRAGMA_VISIBILITY 1 >+extern void push_visibility (const char *); >+extern void pop_visibility (void); > > extern void init_pragma (void); >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 146817
: 96372 |
96373
|
96374
|
96375