This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Class template redeclaration and variadic templates (PR c++/34314)
- From: "Doug Gregor" <doug dot gregor at gmail dot com>
- To: "GCC Patches" <gcc-patches at gcc dot gnu dot org>, "Jason Merrill" <jason at redhat dot com>
- Date: Mon, 14 Jan 2008 19:10:10 -0500
- Subject: [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 ...'" }