diff mbox

C++ PATCH for c++/58606 (ICE with partial specialization in variadic template)

Message ID 52E72E08.5050905@redhat.com
State New
Headers show

Commit Message

Jason Merrill Jan. 28, 2014, 4:11 a.m. UTC
We had been representing a template non-type parameter as the plain 
TEMPLATE_PARM_INDEX in the CLASSTYPE_TI_ARGS of the template, even for a 
reference.  But when we substitute into that, the reference 
automatically decays, so it gets wrapped in an INDIRECT_REF that then 
doesn't compare the same as the TEMPLATE_PARM_INDEX by itself.  We've 
worked around that in tsubst_template_arg by stripping the INDIRECT_REF 
again, but tsubst_pack_expansion wasn't doing that.  Rather than add the 
same code there, I decided to call convert_from_reference when building 
the TI_ARGS, so that we don't need any special handling later.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.
diff mbox

Patch

commit 598166a22b0b94663860c279dd6a51fc8e73eb74
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jan 27 13:12:05 2014 -0500

    	PR c++/58606
    	* pt.c (template_parm_to_arg): Call convert_from_reference.
    	(tsubst_template_arg): Don't strip reference refs.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4414e49..661143a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3854,6 +3854,7 @@  template_parm_to_arg (tree t)
 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
 	    (vec, TREE_VEC_LENGTH (vec));
 #endif
+	  t = convert_from_reference (t);
 	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
 
 	  t  = make_node (NONTYPE_ARGUMENT_PACK);
@@ -9281,10 +9282,6 @@  tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 		       /*integral_constant_expression_p=*/true);
       if (!(complain & tf_warning))
 	--c_inhibit_evaluation_warnings;
-      /* Preserve the raw-reference nature of T.  */
-      if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
-	  && REFERENCE_REF_P (r))
-	r = TREE_OPERAND (r, 0);
     }
   return r;
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic146.C b/gcc/testsuite/g++.dg/cpp0x/variadic146.C
new file mode 100644
index 0000000..0c91db5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic146.C
@@ -0,0 +1,9 @@ 
+// PR c++/58606
+// { dg-require-effective-target c++11 }
+
+template<int&...I> struct A
+{
+  template<typename> struct B;
+
+  template<typename T> struct B<T*> {};
+};