Patchwork [C++,committed] Fix make_ith_pack_parameter_name ICE (PR c++/55542)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 30, 2012, 11:53 p.m.
Message ID <20121130235351.GJ2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/203083/
State New
Headers show

Comments

Jakub Jelinek - Nov. 30, 2012, 11:53 p.m.
Hi!

If the pack is unnamed, make_ith_pack_parameter_name will crash.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
acked by Jason in the PR, committed to trunk so far.

2012-12-01  Jakub Jelinek  <jakub@redhat.com>

	PR c++/55542
	* pt.c (make_ith_pack_parameter_name): Return NULL if
	name is NULL.
	(tsubst_decl): Call make_ith_pack_parameter_name even if
	DECL_NAME is NULL.

	* g++.dg/cpp0x/vt-55542.C: New test.


	Jakub

Patch

--- gcc/cp/pt.c.jj	2012-11-19 14:41:16.000000000 +0100
+++ gcc/cp/pt.c	2012-11-30 09:24:45.716620002 +0100
@@ -2905,6 +2905,8 @@  make_ith_pack_parameter_name (tree name,
   char* newname;
   int newname_len;
 
+  if (name == NULL_TREE)
+    return name;
   snprintf (numbuf, NUMBUF_LEN, "%i", i);
   newname_len = IDENTIFIER_LENGTH (name)
 	        + strlen (numbuf) + 2;
@@ -10267,10 +10269,9 @@  tsubst_decl (tree t, tree args, tsubst_f
                 /* Get the Ith type.  */
                 type = TREE_VEC_ELT (expanded_types, i);
 
-                if (DECL_NAME (r))
-                  /* Rename the parameter to include the index.  */
-                  DECL_NAME (r) =
-                    make_ith_pack_parameter_name (DECL_NAME (r), i);
+		/* Rename the parameter to include the index.  */
+		DECL_NAME (r)
+		  = make_ith_pack_parameter_name (DECL_NAME (r), i);
               }
             else if (!type)
               /* We're dealing with a normal parameter.  */
--- gcc/testsuite/g++.dg/cpp0x/vt-55542.C.jj	2012-11-30 09:37:14.042107481 +0100
+++ gcc/testsuite/g++.dg/cpp0x/vt-55542.C	2012-11-30 09:35:02.000000000 +0100
@@ -0,0 +1,22 @@ 
+// PR c++/55542
+// { dg-options "-std=c++11" }
+
+template <typename ... P>
+struct B
+{
+  template <typename O>
+  B (O *o, void (O::*f) (P ... p)) {}
+};
+class C
+{
+  void foo (void *, int);
+  template <typename ... A>
+  void bar (A ... a);
+  B <void *> c;
+  B <void *, int> d;
+  C (int) : c (this, &C::bar), d (this, &C::foo) {}
+};
+template <typename ... A>
+void C::bar (A ...)
+{
+}