PR c++/35688
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Nov 2011 04:40:14 +0000 (04:40 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Nov 2011 04:40:14 +0000 (04:40 +0000)
gcc/c-common/
* c-common.c (decl_has_visibility_attr): Split out from...
(c_determine_visibility): ...here.
* c-common.h: Declare it.
gcc/cp/
* decl2.c (constrain_visibility): Check decl_has_visibility_attr
rather than DECL_VISIBILITY_SPECIFIED.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181069 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/visibility/template7.C [new file with mode: 0644]

index 3829411..7b30b3b 100644 (file)
@@ -1,3 +1,10 @@
+2011-11-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35688
+       * c-common.c (decl_has_visibility_attr): Split out from...
+       (c_determine_visibility): ...here.
+       * c-common.h: Declare it.
+
 2011-11-06  Joseph Myers  <joseph@codesourcery.com>
 
        * c-common.c (c_common_reswords): Add _Alignas and _Alignof.
index 0329bc7..92fb363 100644 (file)
@@ -7073,6 +7073,22 @@ handle_visibility_attribute (tree *node, tree name, tree args,
   return NULL_TREE;
 }
 
+/* Returns true iff DECL actually has visibility specified by an attribute.
+   We check for an explicit attribute, rather than just checking
+   DECL_VISIBILITY_SPECIFIED, to distinguish the use of an attribute from
+   the use of a "#pragma GCC visibility push(...)"; in the latter case we
+   still want other considerations to be able to overrule the #pragma.  */
+
+bool
+decl_has_visibility_attr (tree decl)
+{
+  tree attrs = DECL_ATTRIBUTES (decl);
+  return (lookup_attribute ("visibility", attrs)
+         || (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+             && (lookup_attribute ("dllimport", attrs)
+                 || lookup_attribute ("dllexport", attrs))));
+}
+
 /* Determine the ELF symbol visibility for DECL, which is either a
    variable or a function.  It is an error to use this function if a
    definition of DECL is not available in this translation unit.
@@ -7088,15 +7104,8 @@ c_determine_visibility (tree decl)
 
   /* If the user explicitly specified the visibility with an
      attribute, honor that.  DECL_VISIBILITY will have been set during
-     the processing of the attribute.  We check for an explicit
-     attribute, rather than just checking DECL_VISIBILITY_SPECIFIED,
-     to distinguish the use of an attribute from the use of a "#pragma
-     GCC visibility push(...)"; in the latter case we still want other
-     considerations to be able to overrule the #pragma.  */
-  if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl))
-      || (TARGET_DLLIMPORT_DECL_ATTRIBUTES
-         && (lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl))
-             || lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))))
+     the processing of the attribute.  */
+  if (decl_has_visibility_attr (decl))
     return true;
 
   /* Set default visibility to whatever the user supplied with
index bff6956..f914d49 100644 (file)
@@ -775,6 +775,7 @@ extern void overflow_warning (location_t, tree);
 extern void warn_logical_operator (location_t, enum tree_code, tree,
                                   enum tree_code, tree, enum tree_code, tree);
 extern void check_main_parameter_types (tree decl);
+extern bool decl_has_visibility_attr (tree);
 extern bool c_determine_visibility (tree);
 extern bool same_scalar_type_ignoring_signedness (tree, tree);
 extern void mark_valid_location_for_stdc_pragma (bool);
index f374af6..201c2c1 100644 (file)
@@ -1,3 +1,9 @@
+2011-11-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35688
+       * decl2.c (constrain_visibility): Check decl_has_visibility_attr
+       rather than DECL_VISIBILITY_SPECIFIED.
+
 2011-11-06  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/47695
index f4499b5..80fb0c3 100644 (file)
@@ -1974,8 +1974,11 @@ constrain_visibility (tree decl, int visibility)
            DECL_NOT_REALLY_EXTERN (decl) = 1;
        }
     }
+  /* We check decl_has_visibility_attr rather than
+     DECL_VISIBILITY_SPECIFIED here because we want other considerations
+     to override visibility from a namespace or #pragma.  */
   else if (visibility > DECL_VISIBILITY (decl)
-          && !DECL_VISIBILITY_SPECIFIED (decl))
+          && !decl_has_visibility_attr (decl))
     {
       DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility;
       return true;
index fc0938c..1f9aa81 100644 (file)
@@ -1,3 +1,8 @@
+2011-11-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35688
+       * g++.dg/ext/visibility/template7.C: New.
+
 2011-11-07  Terry Guo  <terry.guo@arm.com>
 
        * gcc.target/arm/wmul-1.c: Adjust optimization level.
diff --git a/gcc/testsuite/g++.dg/ext/visibility/template7.C b/gcc/testsuite/g++.dg/ext/visibility/template7.C
new file mode 100644 (file)
index 0000000..5197fb1
--- /dev/null
@@ -0,0 +1,29 @@
+// PR c++/35688
+// { dg-require-visibility "" }
+// { dg-options "-fvisibility=hidden" }
+
+// { dg-final { scan-hidden "_ZN1s6vectorI1AEC1Ev" } }
+// { dg-final { scan-hidden "_ZN1s3fooI1AEEvT_" } }
+
+namespace s __attribute__((visibility("default"))) {
+  template <class T>
+    class vector {
+  public:
+    vector() { }
+  };
+  template <class T>
+    void foo(T t) {
+  }
+}
+
+class A {
+public:
+  A() { }
+};
+
+s::vector<A> v;
+
+int main() {
+  A a;
+  s::foo(a);
+}