From 22197246e3547e2838192d45b29b03761544588a Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Mon, 23 Jan 2012 15:48:31 -0500
Subject: [PATCH] re PR c++/51930 (Explicitly instantiated template gets hidden
 visibility)

	PR c++/51930
	* decl2.c (determine_visibility): Check for visibility attribute
	on template specialization.

From-SVN: r183455
---
 gcc/cp/ChangeLog                                 |  6 ++++++
 gcc/cp/decl2.c                                   |  8 +++++++-
 gcc/testsuite/ChangeLog                          |  5 +++++
 gcc/testsuite/g++.dg/ext/visibility/template10.C | 16 ++++++++++++++++
 4 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/visibility/template10.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 13f34845818a..11d458a36446 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2012-01-23  Jason Merrill  <jason@redhat.com>
+
+	PR c++/51930
+	* decl2.c (determine_visibility): Check for visibility attribute
+	on template specialization.
+
 2012-01-23  Paolo Carlini  <paolo.carlini@oracle.com>
 
 	PR c++/51398
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f51790c551d1..bdc962abcf9b 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2177,8 +2177,14 @@ determine_visibility (tree decl)
 		    ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
 		    : DECL_TEMPLATE_INFO (decl));
       tree args = TI_ARGS (tinfo);
+      tree attribs = (TREE_CODE (decl) == TYPE_DECL
+		      ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
+		      : DECL_ATTRIBUTES (decl));
       
-      if (args != error_mark_node)
+      if (args != error_mark_node
+	  /* Template argument visibility outweighs #pragma or namespace
+	     visibility, but not an explicit attribute.  */
+	  && !lookup_attribute ("visibility", attribs))
 	{
 	  int depth = TMPL_ARGS_DEPTH (args);
 	  tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0f1e4bf2bb88..43794d3e5eba 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-23  Jason Merrill  <jason@redhat.com>
+
+	PR c++/51930
+	* g++.dg/ext/visibility/template10.C: New.
+
 2012-01-23  Tobias Burnus  <burnus@net-b.de>
 
 	PR fortran/51948
diff --git a/gcc/testsuite/g++.dg/ext/visibility/template10.C b/gcc/testsuite/g++.dg/ext/visibility/template10.C
new file mode 100644
index 000000000000..01108aa7f424
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/template10.C
@@ -0,0 +1,16 @@
+// PR c++/51930
+// { dg-require-visibility }
+// { dg-options -fvisibility=hidden }
+// { dg-final { scan-not-hidden "_Z8testfuncI3fooEvv" } }
+
+struct foo { };
+
+template<typename T>
+__attribute__ ((visibility("default")))
+void testfunc();
+
+template<typename T> void testfunc() { }
+
+template
+__attribute__ ((visibility("default")))
+void testfunc<foo>();
-- 
GitLab