diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e464d91b914fe008056dd3e0f985a7d5c7a17ed6..0b6ec64b5efae8c0654e121a6175fb355adef98b 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 d3d9975a3d6bf492b13e690f87124b94f16b3299..b589fd2805ae7dbd05038347e215be09a313fc7f 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 409b123a480416999b23e097a5a1476ff446ea3c..d364b20e9c568d03d0aa2e4a1c47296f3dacf7fd 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 3ae7f9d079aeb339b765097ba58732b6db77f2e4..c6479e04fe50249e56c7be68ebf7c1d8295432bb 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 0000000000000000000000000000000000000000..4a935b367d6577d0c29838ffef9493acf1958f6b --- /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; + }; +};