From: Jason Merrill Date: Fri, 21 Jul 2006 21:00:20 +0000 (-0400) Subject: decl2.c (determine_visibility): Don't propagate visibility from type to decl. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bd741f34c92ccea7a44b4ba632ed7e648e662708;p=platform%2Fupstream%2Fgcc.git decl2.c (determine_visibility): Don't propagate visibility from type to decl. * decl2.c (determine_visibility): Don't propagate visibility from type to decl. (constrain_class_visibility): Don't warn in system headers. Don't warn about pointer fields. From-SVN: r115651 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a647341..d8af5068 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -14,6 +14,7 @@ 2006-07-20 Jason Merrill * tree.c (remove_attribute): New fn. + * tree.h: Declare it. 2006-07-20 Paul Brook diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f74d1a7..50f8381 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2006-07-21 Jason Merrill + + * decl2.c (determine_visibility): Don't propagate visibility from + type to decl. + (constrain_class_visibility): Don't warn in system headers. + Don't warn about pointer fields. + 2006-07-20 Mike Stump * decl2.c (determine_visibility_from_class): Don't use hidden diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 876dea3..faee0aa 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1775,17 +1775,17 @@ determine_visibility (tree decl) if (class_type) determine_visibility_from_class (decl, class_type); - /* 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)))) - warning (OPT_Wattributes, "\ -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_ANON); + else if (TREE_CODE (decl) != TYPE_DECL) + { + /* Propagate anonymity from type to decl. */ + int tvis = type_visibility (TREE_TYPE (decl)); + if (tvis == VISIBILITY_ANON) + constrain_visibility (decl, tvis); + } } /* By default, static data members and function members receive @@ -1841,7 +1841,8 @@ constrain_class_visibility (tree type) int vis = type_visibility (type); - if (vis == VISIBILITY_ANON) + if (vis == VISIBILITY_ANON + || DECL_IN_SYSTEM_HEADER (TYPE_MAIN_DECL (type))) return; /* Don't warn about visibility if the class has explicit visibility. */ @@ -1851,13 +1852,15 @@ constrain_class_visibility (tree type) for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node) { - int subvis = type_visibility (TREE_TYPE (t)); + tree ftype = strip_array_types (TREE_TYPE (t)); + int subvis = type_visibility (ftype); if (subvis == VISIBILITY_ANON) warning (0, "\ %qT has a field %qD whose type uses the anonymous namespace", type, t); - else if (vis < VISIBILITY_HIDDEN + else if (IS_AGGR_TYPE (ftype) + && vis < VISIBILITY_HIDDEN && subvis >= VISIBILITY_HIDDEN) warning (OPT_Wattributes, "\ %qT declared with greater visibility than the type of its field %qD", diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 28a0a5b..9197589 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1625,7 +1625,8 @@ the function is defined in only one shared object. You may mark a method as having a visibility explicitly to negate the effect of the switch for that method. For example, if you do want to compare pointers to a particular inline method, you might mark it as -having default visibility. +having default visibility. Marking the enclosing class with explicit +visibility will have no effect. Explicitly instantiated inline methods are unaffected by this option as their linkage might otherwise cross a shared library boundary. diff --git a/gcc/testsuite/g++.dg/ext/visibility/warn1.C b/gcc/testsuite/g++.dg/ext/visibility/warn1.C deleted file mode 100644 index 3b6b85f..0000000 --- a/gcc/testsuite/g++.dg/ext/visibility/warn1.C +++ /dev/null @@ -1,13 +0,0 @@ -// Warn when a declaration is specified with greater visibility than that -// of its type. - -// { dg-do compile } -// { dg-require-visibility "" } -// { dg-final { scan-hidden "_Z1fv" } } - -namespace N __attribute ((__visibility__ ("hidden"))) -{ - struct A { }; -} - -N::A f() { } // { dg-warning "visibility" "" } diff --git a/gcc/testsuite/g++.dg/ext/visibility/warn2.C b/gcc/testsuite/g++.dg/ext/visibility/warn2.C index 54354b5..3a9637d 100644 --- a/gcc/testsuite/g++.dg/ext/visibility/warn2.C +++ b/gcc/testsuite/g++.dg/ext/visibility/warn2.C @@ -1,6 +1,5 @@ // Complain when a class is specified with greater visibility than one of -// its members' types or bases, and when a declaration has greater -// visibility than its type. +// its members' types or bases. // { dg-require-visibility "" } @@ -14,6 +13,4 @@ struct B N::A a; }; -N::A f () { } // { dg-warning "visibility" } - struct C: public N::A { }; // { dg-warning "visibility" } diff --git a/gcc/testsuite/g++.dg/ext/visibility/warn3.C b/gcc/testsuite/g++.dg/ext/visibility/warn3.C index de64217..2d4ec40 100644 --- a/gcc/testsuite/g++.dg/ext/visibility/warn3.C +++ b/gcc/testsuite/g++.dg/ext/visibility/warn3.C @@ -12,14 +12,8 @@ struct __attribute ((visibility ("hidden"))) A 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. +// This gets a warning because B objects might rely +// on hidden symbols from A. struct B { // { dg-warning "visibility" } A a;