From: Douglas Gregor Date: Tue, 15 Jan 2008 16:06:48 +0000 (+0000) Subject: re PR c++/34052 (Trouble with variadic templates as template-template parameter) X-Git-Tag: releases/gcc-4.3.0~613 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85d852346c60093ad0f749aefecf6c8c46f9a2b5;p=thirdparty%2Fgcc.git re PR c++/34052 (Trouble with variadic templates as template-template parameter) 2008-01-15 Douglas Gregor PR c++/34052 * pt.c (check_default_tmpl_args): Check for parameter packs that aren't at the end of a primary template. (push_template_decl_real): Remove check for parameter packs that aren't at the end of a primary template; that now happens in check_default_tmpl_args. * semantics.c (finish_template_template_parm): Use check_default_tmpl_args to check for errors in the template parameter list. 2008-01-15 Douglas Gregor PR c++/34052 * g++.dg/cpp0x/vt-34052.C: New. * g++.dg/template/ttp26.C: New. From-SVN: r131543 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c46c07251a45..4125ade97577 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2008-01-15 Douglas Gregor + + PR c++/34052 + * pt.c (check_default_tmpl_args): Check for parameter packs that + aren't at the end of a primary template. + (push_template_decl_real): Remove check for parameter packs that + aren't at the end of a primary template; that now happens in + check_default_tmpl_args. + * semantics.c (finish_template_template_parm): Use + check_default_tmpl_args to check for errors in the template + parameter list. + 2008-01-12 Doug Kwan * decl.c: (grokdeclarator): Use OPT_Wignored_qualifiers diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f25f2c403049..b9c40b209b10 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3537,10 +3537,11 @@ process_partial_specialization (tree decl) return decl; } -/* Check that a template declaration's use of default arguments is not - invalid. Here, PARMS are the template parameters. IS_PRIMARY is - nonzero if DECL is the thing declared by a primary template. - IS_PARTIAL is nonzero if DECL is a partial specialization. +/* Check that a template declaration's use of default arguments and + parameter packs is not invalid. Here, PARMS are the template + parameters. IS_PRIMARY is nonzero if DECL is the thing declared by + a primary template. IS_PARTIAL is nonzero if DECL is a partial + specialization. IS_FRIEND_DECL is nonzero if DECL is a friend function template @@ -3625,6 +3626,29 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, TREE_PURPOSE (parm) = error_mark_node; no_errors = false; } + else if (is_primary + && !is_partial + && !is_friend_decl + && TREE_CODE (decl) == TYPE_DECL + && i < ntparms - 1 + && template_parameter_pack_p (TREE_VALUE (parm))) + { + /* A primary class template can only have one + parameter pack, at the end of the template + parameter list. */ + + if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL) + error ("parameter pack %qE must be at the end of the" + " template parameter list", TREE_VALUE (parm)); + else + error ("parameter pack %qT must be at the end of the" + " template parameter list", + TREE_TYPE (TREE_VALUE (parm))); + + TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) + = error_mark_node; + no_errors = false; + } } } } @@ -3888,31 +3912,6 @@ push_template_decl_real (tree decl, bool is_friend) if (is_partial) return process_partial_specialization (decl); - /* A primary class template can only have one parameter pack, at the - end of the template parameter list. */ - if (primary && TREE_CODE (decl) == TYPE_DECL) - { - tree inner_parms - = INNERMOST_TEMPLATE_PARMS (current_template_parms); - int i, len = TREE_VEC_LENGTH (inner_parms); - for (i = 0; i < len - 1; i++) - { - tree parm = TREE_VALUE (TREE_VEC_ELT (inner_parms, i)); - - if (template_parameter_pack_p (parm)) - { - if (TREE_CODE (parm) == PARM_DECL) - error ("parameter pack %qE must be at the end of the" - " template parameter list", parm); - else - error ("parameter pack %qT must be at the end of the" - " template parameter list", TREE_TYPE (parm)); - - TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) = error_mark_node; - } - } - } - args = current_template_args (); if (!ctx diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 5df43d5ad16a..0e8c435dcc8b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2191,6 +2191,10 @@ finish_template_template_parm (tree aggr, tree identifier) gcc_assert (DECL_TEMPLATE_PARMS (tmpl)); + check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl), + /*is_primary=*/true, /*is_partial=*/false, + /*is_friend=*/0); + return finish_template_type_parm (aggr, tmpl); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac27643aeea6..7aef4010b282 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-01-15 Douglas Gregor + + PR c++/34052 + * g++.dg/cpp0x/vt-34052.C: New. + * g++.dg/template/ttp26.C: New. + 2008-01-14 Eric Botcazou * gnat.dg/rep_clause2.ad[sb]: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34052.C b/gcc/testsuite/g++.dg/cpp0x/vt-34052.C new file mode 100644 index 000000000000..15310cfe74d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-34052.C @@ -0,0 +1,8 @@ +// { dg-options "-std=c++0x" } +template struct A {}; // { dg-error "must be at the end" } + + +template class U> struct B // { dg-error "must be at the end" } +{ + template U foo(); // { dg-error "mismatch|constant|invalid|invalid" } +}; diff --git a/gcc/testsuite/g++.dg/template/ttp26.C b/gcc/testsuite/g++.dg/template/ttp26.C new file mode 100644 index 000000000000..6ba5cb28a0a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp26.C @@ -0,0 +1,5 @@ +// PR c++/34052 +template class C; // { dg-error "no default argument" } + +template class C> struct X; // { dg-error "no default argument" } +