aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2006-07-21 17:00:20 -0400
committerJason Merrill <jason@gcc.gnu.org>2006-07-21 17:00:20 -0400
commitbd741f34c92ccea7a44b4ba632ed7e648e662708 (patch)
tree4358496ac7765b7190f74685463f436591717ff0
parent505692b0cd8319bb23012fd510d0f26cebccea87 (diff)
downloadgcc-bd741f34c92ccea7a44b4ba632ed7e648e662708.zip
gcc-bd741f34c92ccea7a44b4ba632ed7e648e662708.tar.gz
gcc-bd741f34c92ccea7a44b4ba632ed7e648e662708.tar.bz2
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
-rw-r--r--gcc/ChangeLog1
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl2.c23
-rw-r--r--gcc/doc/invoke.texi3
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/warn1.C13
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/warn2.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/warn3.C10
7 files changed, 26 insertions, 36 deletions
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 <jason@redhat.com>
* tree.c (remove_attribute): New fn.
+ * tree.h: Declare it.
2006-07-20 Paul Brook <paul@codesourcery.com>
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 <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
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;