Patchwork C++ PATCH for c++/57317 (wrong visibility with template args)

login
register
mail settings
Submitter Jason Merrill
Date May 20, 2013, 12:27 p.m.
Message ID <519A16C0.3040908@redhat.com>
Download mbox | patch
Permalink /patch/245016/
State New
Headers show

Comments

Jason Merrill - May 20, 2013, 12:27 p.m.
The way I was testing for whether or not we need to look at template 
args for a particular decl was broken; DECL_TI_ARGS may not reflect the 
number of template headers for the enclosing class if that class is an 
explicit specialization.

Tested x86_64-pc-linux-gnu, applying to trunk.  Jakub: it would be nice 
to get this into 4.8.1, since it affects symbol visibility.  What do you 
think?
Jakub Jelinek - May 20, 2013, 1:03 p.m.
On Mon, May 20, 2013 at 08:27:44AM -0400, Jason Merrill wrote:
> The way I was testing for whether or not we need to look at template
> args for a particular decl was broken; DECL_TI_ARGS may not reflect
> the number of template headers for the enclosing class if that class
> is an explicit specialization.
> 
> Tested x86_64-pc-linux-gnu, applying to trunk.  Jakub: it would be
> nice to get this into 4.8.1, since it affects symbol visibility.
> What do you think?

If you feel it is safe for 4.8.1, let's apply it there.

> commit 761bc243b609db7b75f71f465812e0491212d63b
> Author: Jason Merrill <jason@redhat.com>
> Date:   Fri May 17 16:06:04 2013 -0400
> 
>     	PR c++/57317
>     	* decl2.c (determine_visibility): Use PRIMARY_TEMPLATE_P to decide
>     	whether a template has its own args.

	Jakub

Patch

commit 761bc243b609db7b75f71f465812e0491212d63b
Author: Jason Merrill <jason@redhat.com>
Date:   Fri May 17 16:06:04 2013 -0400

    	PR c++/57317
    	* decl2.c (determine_visibility): Use PRIMARY_TEMPLATE_P to decide
    	whether a template has its own args.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index b91408a..628be93 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2213,9 +2213,6 @@  determine_visibility (tree decl)
 	      && !lookup_attribute ("visibility", attribs))
 	    {
 	      int depth = TMPL_ARGS_DEPTH (args);
-	      int class_depth = 0;
-	      if (class_type && CLASSTYPE_TEMPLATE_INFO (class_type))
-		class_depth = TMPL_ARGS_DEPTH (CLASSTYPE_TI_ARGS (class_type));
 	      if (DECL_VISIBILITY_SPECIFIED (decl))
 		{
 		  /* A class template member with explicit visibility
@@ -2228,7 +2225,7 @@  determine_visibility (tree decl)
 		      constrain_visibility_for_template (decl, lev);
 		    }
 		}
-	      else if (depth > class_depth)
+	      else if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)))
 		/* Limit visibility based on its template arguments.  */
 		constrain_visibility_for_template (decl, args);
 	    }
diff --git a/gcc/testsuite/g++.dg/warn/anonymous-namespace-4.C b/gcc/testsuite/g++.dg/warn/anonymous-namespace-4.C
new file mode 100644
index 0000000..7d1e89e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/anonymous-namespace-4.C
@@ -0,0 +1,12 @@ 
+// PR c++/57137
+
+#include "anonymous-namespace-4.h"
+
+namespace
+{
+  class NonCloneable;
+  void fn1 ()
+  {
+    is_function_impl < NonCloneable > i;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/warn/anonymous-namespace-4.h b/gcc/testsuite/g++.dg/warn/anonymous-namespace-4.h
new file mode 100644
index 0000000..e0b7d68
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/anonymous-namespace-4.h
@@ -0,0 +1,14 @@ 
+template < typename T > struct integral_c {
+  static const T value = 0;
+};
+struct is_reference:integral_c < bool > { };
+template < class > struct is_function_ptr_helper { };
+template < bool > struct is_function_chooser;
+
+template <> struct is_function_chooser <0 >
+{
+  template < typename T > struct result_:is_function_ptr_helper < T * > { };
+};
+
+template < typename T > struct is_function_impl:is_function_chooser <
+  is_reference::value >::result_ < T > { };