decl2.c (determine_visibility): Don't propagate visibility from type to decl.
authorJason Merrill <jason@redhat.com>
Fri, 21 Jul 2006 21:00:20 +0000 (17:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 21 Jul 2006 21:00:20 +0000 (17:00 -0400)
        * 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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/doc/invoke.texi
gcc/testsuite/g++.dg/ext/visibility/warn1.C [deleted file]
gcc/testsuite/g++.dg/ext/visibility/warn2.C
gcc/testsuite/g++.dg/ext/visibility/warn3.C

index a647341..d8af506 100644 (file)
@@ -14,6 +14,7 @@
 2006-07-20  Jason Merrill  <jason@redhat.com>
 
        * tree.c (remove_attribute): New fn.
+       * tree.h: Declare it.
 
 2006-07-20  Paul Brook  <paul@codesourcery.com>
 
index f74d1a7..50f8381 100644 (file)
@@ -1,3 +1,10 @@
+2006-07-21  Jason Merrill  <jason@redhat.com>
+
+       * 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  <mrs@apple.com>
 
        * decl2.c (determine_visibility_from_class): Don't use hidden
index 876dea3..faee0aa 100644 (file)
@@ -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",
index 28a0a5b..9197589 100644 (file)
@@ -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 (file)
index 3b6b85f..0000000
+++ /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" "" }
index 54354b5..3a9637d 100644 (file)
@@ -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" }
index de64217..2d4ec40 100644 (file)
@@ -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;