From a022041e4ca05c32d7d17a26ce6f0716b4ba642f Mon Sep 17 00:00:00 2001
From: Douglas Gregor <doug.gregor@gmail.com>
Date: Tue, 15 Jan 2008 17:59:44 +0000
Subject: [PATCH] =?UTF-8?q?re=20PR=20c++/34314=20(ICE=20on=20invalid=20cod?=
 =?UTF-8?q?e=20(with=20variadic=20templates):=20tree=20check:=20expected?=
 =?UTF-8?q?=20class=20=E2=80=98type=E2=80=99,=20have=20=E2=80=98exceptiona?=
 =?UTF-8?q?l=E2=80=99=20(error=5Fmark)=20in=20template=5Fclass=5Fdepth)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/34314
       * error.c (dump_simple_decl): Display ellipsis for template
       non-type parameter packs.
       (dump_decl): Display ellipsis for template type parameter packs.
       (dump_template_decl): Display ellipsis for template template
       parameter packs.
       * pt.c (redeclare_class_template): When redeclaring a class
       template, check for collisions between template parameters and
       template parameter packs.

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/34314
       * g++.dg/cpp0x/vt-34314.C: New.
       * g++.dg/cpp0x/variadic79.C: Fix the error message to reflect
       reality (the error message was wrong previously).

From-SVN: r131546
---
 gcc/cp/ChangeLog                        | 12 ++++++
 gcc/cp/error.c                          | 24 ++++++++++--
 gcc/cp/pt.c                             | 12 ++++--
 gcc/testsuite/g++.dg/cpp0x/variadic79.C |  2 +-
 gcc/testsuite/g++.dg/cpp0x/vt-34314.C   | 50 +++++++++++++++++++++++++
 5 files changed, 92 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/vt-34314.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e464d91b914f..0b6ec64b5efa 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/34314
+       * error.c (dump_simple_decl): Display ellipsis for template
+       non-type parameter packs.
+       (dump_decl): Display ellipsis for template type parameter packs.
+       (dump_template_decl): Display ellipsis for template template
+       parameter packs.
+       * pt.c (redeclare_class_template): When redeclaring a class
+       template, check for collisions between template parameters and
+       template parameter packs.
+
 2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
 
        PR c++/33964
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index d3d9975a3d6b..b589fd2805ae 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -754,6 +754,10 @@ dump_simple_decl (tree t, tree type, int flags)
 	  || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
     dump_scope (CP_DECL_CONTEXT (t), flags);
   flags &= ~TFF_UNQUALIFIED_NAME;
+  if ((flags & TFF_DECL_SPECIFIERS)
+      && DECL_TEMPLATE_PARM_P (t) 
+      && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
+    pp_identifier (cxx_pp, "...");
   if (DECL_NAME (t))
     dump_decl (DECL_NAME (t), flags);
   else
@@ -778,8 +782,14 @@ dump_decl (tree t, int flags)
 	{
 	  if ((flags & TFF_DECL_SPECIFIERS)
 	      && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
-	    /* Say `class T' not just `T'.  */
-	    pp_cxx_identifier (cxx_pp, "class");
+	    {
+	      /* Say `class T' not just `T'.  */
+	      pp_cxx_identifier (cxx_pp, "class");
+
+	      /* Emit the `...' for a parameter pack.  */
+	      if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+		pp_cxx_identifier (cxx_pp, "...");
+	    }
 
 	  dump_type (TREE_TYPE (t), flags);
 	  break;
@@ -1015,8 +1025,14 @@ dump_template_decl (tree t, int flags)
       nreverse(orig_parms);
 
       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
-	/* Say `template<arg> class TT' not just `template<arg> TT'.  */
-	pp_cxx_identifier (cxx_pp, "class");
+	{
+	  /* Say `template<arg> class TT' not just `template<arg> TT'.  */
+	  pp_cxx_identifier (cxx_pp, "class");
+
+	  /* If this is a parameter pack, print the ellipsis.  */
+	  if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+	    pp_cxx_identifier (cxx_pp, "...");
+	}
     }
 
   if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 409b123a4804..d364b20e9c56 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4193,9 +4193,15 @@ redeclare_class_template (tree type, tree parms)
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
 	 TEMPLATE_DECL.  */
       if (tmpl_parm != error_mark_node
-	   && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-	   || (TREE_CODE (tmpl_parm) != TYPE_DECL
-	       && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
+	  && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+	      || (TREE_CODE (tmpl_parm) != TYPE_DECL
+		  && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))
+	      || (TREE_CODE (tmpl_parm) != PARM_DECL
+		  && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (tmpl_parm))
+		      != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm))))
+	      || (TREE_CODE (tmpl_parm) == PARM_DECL
+		  && (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (tmpl_parm))
+		      != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))))))
 	{
 	  error ("template parameter %q+#D", tmpl_parm);
 	  error ("redeclared here as %q#D", parm);
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic79.C b/gcc/testsuite/g++.dg/cpp0x/variadic79.C
index 3ae7f9d079ae..c6479e04fe50 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic79.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic79.C
@@ -4,4 +4,4 @@
 
 template<template<typename> class...> struct A;
 
-template<template<typename...> class... B> struct A<B...> {}; // { dg-error "mismatch|'template<class ...> class B ...'" }
+template<template<typename...> class... B> struct A<B...> {}; // { dg-error "mismatch|'template<class ...> class ... B ...'" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34314.C b/gcc/testsuite/g++.dg/cpp0x/vt-34314.C
new file mode 100644
index 000000000000..4a935b367d65
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34314.C
@@ -0,0 +1,50 @@
+// { dg-options "-std=c++0x" }
+
+template<typename Fun, typename... Args> // { dg-error "template parameter" }
+struct call;
+
+template<typename Fun, typename Arg0>
+struct call // { dg-error "redeclared here" }
+{
+    template<typename Sig>
+    struct result;
+
+    template<typename X, typename Y>
+    struct result<X(Y)>
+    {
+        typedef X type;
+    };
+};
+
+
+template<typename Fun, int... N> // { dg-error "template parameter" }
+struct call2;
+
+template<typename Fun, int N>
+struct call2 // { dg-error "redeclared here" }
+{
+    template<typename Sig>
+    struct result;
+
+    template<typename X, typename Y>
+    struct result<X(Y)>
+    {
+        typedef X type;
+    };
+};
+
+template<typename Fun, template<typename> class... TT> // { dg-error "template parameter" }
+struct call3;
+
+template<typename Fun, template<typename> class TT>
+struct call3 // { dg-error "redeclared here" }
+{
+    template<typename Sig>
+    struct result;
+
+    template<typename X, typename Y>
+    struct result<X(Y)>
+    {
+        typedef X type;
+    };
+};
-- 
GitLab