This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Class template redeclaration and variadic templates (PR c++/34314)


This patch fixes PR c++/34314, a P4 that should really be a P2, as
we've been classifying this kind of failure. The issue is that we fail
to produce a diagnostic when there is an incorrect redefinition of a
variadic class template, then ICE when we try to process that code.
This patch adds in the appropriate semantic check, then updates the
pretty printer to emit ellipses in the right places for parameter
packs.

Tested i686-pc-linux-gnu; okay for mainline?

  - Doug

2008-01-14  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-14  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).
Index: cp/error.c
===================================================================
--- cp/error.c	(revision 131535)
+++ cp/error.c	(working copy)
@@ -754,6 +754,10 @@ dump_simple_decl (tree t, tree type, int
 	  || 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)
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 131535)
+++ cp/pt.c	(working copy)
@@ -4192,9 +4192,15 @@ redeclare_class_template (tree type, tre
       /* 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);
Index: testsuite/g++.dg/cpp0x/vt-34314.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34314.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34314.C	(revision 0)
@@ -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;
+    };
+};
Index: testsuite/g++.dg/cpp0x/variadic79.C
===================================================================
--- testsuite/g++.dg/cpp0x/variadic79.C	(revision 131535)
+++ testsuite/g++.dg/cpp0x/variadic79.C	(working copy)
@@ -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 ...'" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]