From: Douglas Gregor Date: Tue, 15 Jan 2008 17:59:44 +0000 (+0000) Subject: re PR c++/34314 (ICE on invalid code (with variadic templates): tree check: expected... X-Git-Tag: releases/gcc-4.3.0~611 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a022041e4ca05c32d7d17a26ce6f0716b4ba642f;p=thirdparty%2Fgcc.git re PR c++/34314 (ICE on invalid code (with variadic templates): tree check: expected class ‘type’, have ‘exceptional’ (error_mark) in template_class_depth) 2008-01-15 Douglas Gregor 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 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 --- 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 + + 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 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 class TT' not just `template TT'. */ - pp_cxx_identifier (cxx_pp, "class"); + { + /* Say `template class TT' not just `template 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 class...> struct A; -template class... B> struct A {}; // { dg-error "mismatch|'template class B ...'" } +template class... B> struct A {}; // { dg-error "mismatch|'template 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 // { dg-error "template parameter" } +struct call; + +template +struct call // { dg-error "redeclared here" } +{ + template + struct result; + + template + struct result + { + typedef X type; + }; +}; + + +template // { dg-error "template parameter" } +struct call2; + +template +struct call2 // { dg-error "redeclared here" } +{ + template + struct result; + + template + struct result + { + typedef X type; + }; +}; + +template class... TT> // { dg-error "template parameter" } +struct call3; + +template class TT> +struct call3 // { dg-error "redeclared here" } +{ + template + struct result; + + template + struct result + { + typedef X type; + }; +};