aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-11-06 23:40:14 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-11-06 23:40:14 -0500
commit8e7860a17b0c38d5fae79b39f61e2d74a9be65eb (patch)
tree331d493a855e94c131a78809a6e5e3cd9da0986e
parentc0baa6dc73fe81da219a5e8a1b6f83702f7ef879 (diff)
downloadgcc-8e7860a17b0c38d5fae79b39f61e2d74a9be65eb.zip
gcc-8e7860a17b0c38d5fae79b39f61e2d74a9be65eb.tar.gz
gcc-8e7860a17b0c38d5fae79b39f61e2d74a9be65eb.tar.bz2
re PR c++/35688 (template visibility not overridden by template arguments)
PR c++/35688 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. From-SVN: r181069
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c27
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl2.c5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/template7.C29
7 files changed, 70 insertions, 10 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 3829411..7b30b3b 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 0329bc7..92fb363 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index bff6956..f914d49 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f374af6..201c2c1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f4499b5..80fb0c3 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fc0938c..1f9aa81 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..5197fb1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/template7.C
@@ -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);
+}