Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 96375 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]
third patch
99-visibility04.patch (text/plain), 17.21 KB, created by
Jan Jitse Venselaar
on 2006-09-08 03:10:08 UTC
(
hide
)
Description:
third patch
Filename:
MIME Type:
Creator:
Jan Jitse Venselaar
Created:
2006-09-08 03:10:08 UTC
Size:
17.21 KB
patch
obsolete
>Index: gcc/doc/extend.texi >=================================================================== >--- gcc/doc/extend.texi (revision 116505) >+++ gcc/doc/extend.texi (revision 116507) >@@ -2346,6 +2346,9 @@ > Otherwise, template instantiations and specializations default to the > visibility of their template. > >+If both the template and enclosing class have explicit visibility, the >+visibility from the template is used. >+ > @item warn_unused_result > @cindex @code{warn_unused_result} attribute > The @code{warn_unused_result} attribute causes a warning to be emitted >@@ -3465,6 +3468,13 @@ > attributes, the attribute must appear between the initial keyword and > the name of the type; it cannot appear after the body of the type. > >+Note that the type visibility is applied to vague linkage entities >+associated with the class (vtable, typeinfo node, etc.). In >+particular, if a class is thrown as an exception in one shared object >+and caught in another, the class must have default visibility. >+Otherwise the two shared objects will be unable to use the same >+typeinfo node and exception handling will break. >+ > @subsection ARM Type Attributes > > On those ARM targets that support @code{dllimport} (such as Symbian >Index: gcc/tree.c >=================================================================== >--- gcc/tree.c (revision 116505) >+++ gcc/tree.c (revision 116507) >@@ -3461,6 +3461,28 @@ > return NULL_TREE; > } > >+/* Remove any instances of attribute ATTR_NAME in LIST and return the >+ modified list. */ >+ >+tree >+remove_attribute (const char *attr_name, tree list) >+{ >+ tree *p; >+ size_t attr_len = strlen (attr_name); >+ >+ for (p = &list; *p; ) >+ { >+ tree l = *p; >+ gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE); >+ if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l))) >+ *p = TREE_CHAIN (l); >+ else >+ p = &TREE_CHAIN (l); >+ } >+ >+ return list; >+} >+ > /* Return an attribute list that is the union of a1 and a2. */ > > tree >Index: gcc/tree.h >=================================================================== >--- gcc/tree.h (revision 116505) >+++ gcc/tree.h (revision 116507) >@@ -3613,6 +3613,11 @@ > > extern tree lookup_attribute (const char *, tree); > >+/* Remove any instances of attribute ATTR_NAME in LIST and return the >+ modified list. */ >+ >+extern tree remove_attribute (const char *, tree); >+ > /* Given two attributes lists, return a list of their union. */ > > extern tree merge_attributes (tree, tree); >Index: gcc/testsuite/g++.dg/ext/visibility/template6.C >=================================================================== >--- gcc/testsuite/g++.dg/ext/visibility/template6.C (revision 0) >+++ gcc/testsuite/g++.dg/ext/visibility/template6.C (revision 116507) >@@ -0,0 +1,17 @@ >+// Test for explicit visibility taking precedence >+ >+// { dg-require-visibility "" } >+// { dg-final { scan-not-hidden "_ZN1AIiE1fEv" } } >+ >+template <class T> struct A >+{ >+ // This attribute takes precedence over... >+ __attribute ((visibility ("default"))) void f (); >+}; >+ >+template <class T> >+void A<T>::f () >+{ } >+ >+// ...this attribute. >+template struct __attribute ((visibility ("hidden"))) A<int>; >Index: gcc/testsuite/g++.dg/ext/visibility/warn2.C >=================================================================== >--- gcc/testsuite/g++.dg/ext/visibility/warn2.C (revision 116505) >+++ gcc/testsuite/g++.dg/ext/visibility/warn2.C (revision 116507) >@@ -14,6 +14,6 @@ > N::A a; > }; > >-B f () { } // { dg-warning "visibility" } >+N::A f () { } // { dg-warning "visibility" } > > struct C: public N::A { }; // { dg-warning "visibility" } >Index: gcc/testsuite/g++.dg/ext/visibility/warn3.C >=================================================================== >--- gcc/testsuite/g++.dg/ext/visibility/warn3.C (revision 116505) >+++ gcc/testsuite/g++.dg/ext/visibility/warn3.C (revision 116507) >@@ -1,11 +1,32 @@ >-// Warn when a class member is specified to have greater visibility than >-// its class. >+// Tests for various visibility mismatch situations. > > // { dg-require-visibility "" } > >+// { dg-final { scan-not-hidden "_ZN1A1fEv" } } >+ > struct __attribute ((visibility ("hidden"))) A > { >- __attribute ((visibility ("default"))) void f (); // { dg-warning "visibility" } >+ // This is OK, A::f gets default visibility. >+ __attribute ((visibility ("default"))) void f (); > }; > > void A::f() { } >+ >+// This gets a warning; it should have explicit visibility of some sort. >+A* afactory1() { return new A; } // { dg-warning "visibility" } >+ >+// This is OK. >+__attribute ((visibility ("default"))) A* >+afactory2 () { return new A; } >+ >+// This gets a warning. >+struct B >+{ // { dg-warning "visibility" } >+ A a; >+}; >+ >+// This one has explicit visibility, so it doesn't get a warning. >+struct __attribute ((visibility ("default"))) C >+{ >+ A a; >+}; >Index: gcc/testsuite/g++.dg/lookup/anon5.C >=================================================================== >--- gcc/testsuite/g++.dg/lookup/anon5.C (revision 0) >+++ gcc/testsuite/g++.dg/lookup/anon5.C (revision 116507) >@@ -0,0 +1,21 @@ >+// PR c++/28409 >+// shouldIbevisible should be emitted because it's an extern "C" decl with >+// external linkage, even though it's in the anonymous namespace. >+ >+namespace >+{ >+ extern "C" int shouldIbevisible() >+ { >+ return 0; >+ } >+} >+ >+namespace t >+{ >+ extern "C" int shouldIbevisible(void); >+} >+ >+int main(void) >+{ >+ return t::shouldIbevisible(); >+} >Index: gcc/testsuite/g++.dg/template/anon3.C >=================================================================== >--- gcc/testsuite/g++.dg/template/anon3.C (revision 0) >+++ gcc/testsuite/g++.dg/template/anon3.C (revision 116507) >@@ -0,0 +1,20 @@ >+// PR c++/28370 >+// { dg-do run } >+ >+namespace >+{ >+ template<typename T> struct A { static int *a; }; >+ template<typename T> int *A<T>::a = 0; >+} >+ >+int * >+foo () >+{ >+ return A<int>::a; >+} >+ >+int >+main () >+{ >+ return foo() != 0; >+} >Index: gcc/testsuite/g++.dg/template/anon4.C >=================================================================== >--- gcc/testsuite/g++.dg/template/anon4.C (revision 0) >+++ gcc/testsuite/g++.dg/template/anon4.C (revision 116507) >@@ -0,0 +1,10 @@ >+// PR c++/28407 >+// A declaration in the anonymous namespace still has external linkage. >+ >+template <int *P> class A { }; >+namespace >+{ >+ int i; >+} >+ >+A<&i> a; >Index: gcc/cp/decl.c >=================================================================== >--- gcc/cp/decl.c (revision 116505) >+++ gcc/cp/decl.c (revision 116507) >@@ -5274,6 +5274,14 @@ > determine_visibility (decl); > layout_var_decl (decl); > maybe_commonize_var (decl); >+ if (DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) >+ && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl)) >+ { >+ /* This is a const variable with implicit 'static'. Set >+ DECL_THIS_STATIC so we can tell it from variables that are >+ !TREE_PUBLIC because of the anonymous namespace. */ >+ DECL_THIS_STATIC (decl) = 1; >+ } > make_rtl_for_nonlocal_decl (decl, init, /*asmspec=*/NULL); > } > >Index: gcc/cp/tree.c >=================================================================== >--- gcc/cp/tree.c (revision 116505) >+++ gcc/cp/tree.c (revision 116507) >@@ -2189,7 +2189,10 @@ > /* Things that are TREE_PUBLIC have external linkage. */ > if (TREE_PUBLIC (decl)) > return lk_external; >- >+ >+ if (TREE_CODE (decl) == NAMESPACE_DECL) >+ return lk_external; >+ > /* Linkage of a CONST_DECL depends on the linkage of the enumeration > type. */ > if (TREE_CODE (decl) == CONST_DECL) >@@ -2209,6 +2212,14 @@ > if (decl_function_context (decl)) > return lk_none; > >+ /* Members of the anonymous namespace also have TREE_PUBLIC unset, but >+ are considered to have external linkage for language purposes. DECLs >+ really meant to have internal linkage have DECL_THIS_STATIC set. */ >+ if (TREE_CODE (decl) == TYPE_DECL >+ || ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL) >+ && !DECL_THIS_STATIC (decl))) >+ return lk_external; >+ > /* Everything else has internal linkage. */ > return lk_internal; > } >Index: gcc/cp/pt.c >=================================================================== >--- gcc/cp/pt.c (revision 116505) >+++ gcc/cp/pt.c (revision 116507) >@@ -6609,7 +6609,12 @@ > > /* Possibly limit visibility based on template args. */ > DECL_VISIBILITY (r) = VISIBILITY_DEFAULT; >- DECL_VISIBILITY_SPECIFIED (r) = 0; >+ if (DECL_VISIBILITY_SPECIFIED (t)) >+ { >+ DECL_VISIBILITY_SPECIFIED (r) = 0; >+ DECL_ATTRIBUTES (r) >+ = remove_attribute ("visibility", DECL_ATTRIBUTES (r)); >+ } > determine_visibility (r); > } > break; >@@ -6811,7 +6816,12 @@ > { > /* Possibly limit visibility based on template args. */ > DECL_VISIBILITY (r) = VISIBILITY_DEFAULT; >- DECL_VISIBILITY_SPECIFIED (r) = 0; >+ if (DECL_VISIBILITY_SPECIFIED (t)) >+ { >+ DECL_VISIBILITY_SPECIFIED (r) = 0; >+ DECL_ATTRIBUTES (r) >+ = remove_attribute ("visibility", DECL_ATTRIBUTES (r)); >+ } > determine_visibility (r); > } > >Index: gcc/cp/decl2.c >=================================================================== >--- gcc/cp/decl2.c (revision 116505) >+++ gcc/cp/decl2.c (revision 116507) >@@ -737,14 +737,6 @@ > } > } > >-/* Like note_vague_linkage_fn but for variables. */ >- >-static void >-note_vague_linkage_var (tree var) >-{ >- VEC_safe_push (tree, gc, pending_statics, var); >-} >- > /* We have just processed the DECL, which is a static data member. > The other parameters are as for cp_finish_decl. */ > >@@ -763,8 +755,8 @@ > if (!asmspec_tree && current_class_type) > DECL_INITIAL (decl) = error_mark_node; > >- if (! processing_template_decl && TREE_PUBLIC (decl)) >- note_vague_linkage_var (decl); >+ if (! processing_template_decl) >+ VEC_safe_push (tree, gc, pending_statics, decl); > > if (LOCAL_CLASS_P (current_class_type)) > pedwarn ("local class %q#T shall not have static data member %q#D", >@@ -1579,7 +1571,7 @@ > /* A special return value from type_visibility meaning internal > linkage. */ > >-enum { VISIBILITY_STATIC = VISIBILITY_INTERNAL+1 }; >+enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 }; > > /* walk_tree helper function for type_visibility. */ > >@@ -1595,7 +1587,7 @@ > { > if (!TREE_PUBLIC (TYPE_MAIN_DECL (*tp))) > { >- *vis_p = VISIBILITY_STATIC; >+ *vis_p = VISIBILITY_ANON; > return *tp; > } > else if (CLASSTYPE_VISIBILITY (*tp) > *vis_p) >@@ -1615,29 +1607,28 @@ > return vis; > } > >-/* Limit the visibility of DECL to VISIBILITY. SPECIFIED is true if the >- constraint comes from an attribute or pragma; REASON is the source of >- the constraint. */ >+/* Limit the visibility of DECL to VISIBILITY, if not explicitly >+ specified (or if VISIBILITY is static). */ > > static bool >-constrain_visibility (tree decl, int visibility, bool specified, >- const char *reason) >+constrain_visibility (tree decl, int visibility) > { >- if (visibility == VISIBILITY_STATIC) >+ if (visibility == VISIBILITY_ANON) > { >- TREE_PUBLIC (decl) = 0; >- DECL_INTERFACE_KNOWN (decl) = 1; >- if (DECL_LANG_SPECIFIC (decl)) >- DECL_NOT_REALLY_EXTERN (decl) = 1; >+ /* extern "C" declarations aren't affected by the anonymous >+ namespace. */ >+ if (!DECL_EXTERN_C_P (decl)) >+ { >+ TREE_PUBLIC (decl) = 0; >+ DECL_INTERFACE_KNOWN (decl) = 1; >+ if (DECL_LANG_SPECIFIC (decl)) >+ DECL_NOT_REALLY_EXTERN (decl) = 1; >+ } > } >- else if (visibility > DECL_VISIBILITY (decl)) >+ else if (visibility > DECL_VISIBILITY (decl) >+ && !DECL_VISIBILITY_SPECIFIED (decl)) > { >- if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl))) >- warning (OPT_Wattributes, "%q+D: visibility attribute requests " >- "greater visibility than its %s allows", decl, reason); > DECL_VISIBILITY (decl) = visibility; >- if (!DECL_VISIBILITY_SPECIFIED (decl)) >- DECL_VISIBILITY_SPECIFIED (decl) = specified; > return true; > } > return false; >@@ -1670,13 +1661,13 @@ > || TREE_CODE (arg) == FUNCTION_DECL) > { > if (! TREE_PUBLIC (arg)) >- vis = VISIBILITY_STATIC; >+ vis = VISIBILITY_ANON; > else > vis = DECL_VISIBILITY (arg); > } > } > if (vis) >- constrain_visibility (decl, vis, false, "template parameter"); >+ constrain_visibility (decl, vis); > } > } > >@@ -1771,8 +1762,7 @@ > { > /* tinfo visibility is based on the type it's for. */ > constrain_visibility >- (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))), >- false, "type"); >+ (decl, type_visibility (TREE_TYPE (DECL_NAME (decl)))); > } > else if (use_template) > /* Template instantiations and specializations get visibility based >@@ -1788,24 +1778,25 @@ > > if (use_template) > { >+ /* If the specialization doesn't specify visibility, use the >+ visibility from the template. */ > tree tinfo = (TREE_CODE (decl) == TYPE_DECL > ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) > : DECL_TEMPLATE_INFO (decl)); > tree args = TI_ARGS (tinfo); > int depth = TMPL_ARGS_DEPTH (args); >+ tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)); > >- /* If the template has explicit visibility and the specialization >- doesn't, use the visibility from the template. */ > if (!DECL_VISIBILITY_SPECIFIED (decl)) > { >- tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)); > DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern); >+ DECL_VISIBILITY_SPECIFIED (decl) >+ = DECL_VISIBILITY_SPECIFIED (pattern); > } > > /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */ > if (args && depth > template_class_depth (class_type)) >- /* Don't let it have more visibility than its template type >- arguments. */ >+ /* Limit visibility based on its template arguments. */ > constrain_visibility_for_template (decl, args); > } > >@@ -1814,17 +1805,15 @@ > > /* Don't let it have more visibility than its type. */ > if (TREE_CODE (decl) != TYPE_DECL) >- if (constrain_visibility (decl, type_visibility (TREE_TYPE (decl)), >- false, "type")) >+ if (constrain_visibility (decl, type_visibility (TREE_TYPE (decl)))) > warning (OPT_Wattributes, "\ >-%q+D declared with greater visibility than its type", >+lowering visibility of %q+D to match its type", > decl); > > if (decl_anon_ns_mem_p (decl)) > /* Names in an anonymous namespace get internal linkage. > This might change once we implement export. */ >- constrain_visibility (decl, VISIBILITY_STATIC, >- false, "namespace"); >+ constrain_visibility (decl, VISIBILITY_ANON); > } > > /* By default, static data members and function members receive >@@ -1842,12 +1831,14 @@ > && TREE_CODE (decl) == FUNCTION_DECL > && DECL_DECLARED_INLINE_P (decl)) > DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; >+ else if (!DECL_VISIBILITY_SPECIFIED (decl)) >+ { >+ /* Default to the class visibility. */ >+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); >+ DECL_VISIBILITY_SPECIFIED (decl) >+ = CLASSTYPE_VISIBILITY_SPECIFIED (class_type); >+ } > >- /* The decl can't have more visibility than its class. */ >- constrain_visibility (decl, CLASSTYPE_VISIBILITY (class_type), >- CLASSTYPE_VISIBILITY_SPECIFIED (class_type), >- "class"); >- > /* Give the target a chance to override the visibility associated > with DECL. */ > if (TREE_CODE (decl) == VAR_DECL >@@ -1859,8 +1850,8 @@ > && !DECL_CONSTRUCTION_VTABLE_P (decl))) > && TREE_PUBLIC (decl) > && !DECL_REALLY_EXTERN (decl) >- && DECL_VISIBILITY_SPECIFIED (decl) >- && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))) >+ && !DECL_VISIBILITY_SPECIFIED (decl) >+ && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)) > targetm.cxx.determine_class_data_visibility (decl); > } > >@@ -1870,25 +1861,50 @@ > void > constrain_class_visibility (tree type) > { >- tree decl = TYPE_MAIN_DECL (type); >- tree binfo = TYPE_BINFO (type); >+ tree binfo; > tree t; > int i; > >+ int vis = type_visibility (type); >+ >+ if (vis == VISIBILITY_ANON) >+ return; >+ >+ /* Don't warn about visibility if the class has explicit visibility. */ >+ if (CLASSTYPE_VISIBILITY_SPECIFIED (type)) >+ vis = VISIBILITY_INTERNAL; >+ > for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) >- if (TREE_CODE (t) == FIELD_DECL) >- if (constrain_visibility (decl, type_visibility (TREE_TYPE (t)), >- false, "field type")) >- warning (OPT_Wattributes, "\ >+ if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node) >+ { >+ int subvis = type_visibility (TREE_TYPE (t)); >+ >+ if (subvis == VISIBILITY_ANON) >+ warning (0, "\ >+%qT has a field %qD whose type uses the anonymous namespace", >+ type, t); >+ else if (vis < VISIBILITY_HIDDEN >+ && subvis >= VISIBILITY_HIDDEN) >+ warning (OPT_Wattributes, "\ > %qT declared with greater visibility than the type of its field %qD", >- type, t); >+ type, t); >+ } > >+ binfo = TYPE_BINFO (type); > for (i = 0; BINFO_BASE_ITERATE (binfo, i, t); ++i) >- if (constrain_visibility (decl, type_visibility (TREE_TYPE (t)), >- false, "base type")) >- warning (OPT_Wattributes, "\ >+ { >+ int subvis = type_visibility (TREE_TYPE (t)); >+ >+ if (subvis == VISIBILITY_ANON) >+ warning (0, "\ >+%qT has a base %qT whose type uses the anonymous namespace", >+ type, TREE_TYPE (t)); >+ else if (vis < VISIBILITY_HIDDEN >+ && subvis >= VISIBILITY_HIDDEN) >+ warning (OPT_Wattributes, "\ > %qT declared with greater visibility than its base %qT", >- type, TREE_TYPE (t)); >+ type, TREE_TYPE (t)); >+ } > } > > /* DECL is a FUNCTION_DECL or VAR_DECL. If the object file linkage
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