From 37457866673a1ed44cec3395459dc0c4f0135da2 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 19 Jul 2011 13:28:13 -0400 Subject: [PATCH] re PR c++/49785 ([C++0x] ICE in coerce_template_parms) PR c++/49785 * pt.c (coerce_template_parms): Handle non-pack after pack. From-SVN: r176472 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/pt.c | 22 +++++++++++-------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/variadic114.C | 27 ++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic114.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f80f7b6916a..2f5be0ac1e5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2011-07-19 Jason Merrill + + PR c++/49785 + * pt.c (coerce_template_parms): Handle non-pack after pack. + 2011-07-19 Richard Guenther * call.c (build_special_member_call): Use fold_build_pointer_plus. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f34e1df818b..178685c40d4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6537,6 +6537,7 @@ coerce_template_parms (tree parms, subtract it from nparms to get the number of non-variadic parameters. */ int variadic_p = 0; + int post_variadic_parms = 0; if (args == error_mark_node) return error_mark_node; @@ -6547,19 +6548,22 @@ coerce_template_parms (tree parms, for (parm_idx = 0; parm_idx < nparms; ++parm_idx) { tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx)); + if (variadic_p) + ++post_variadic_parms; if (template_parameter_pack_p (tparm)) ++variadic_p; } inner_args = INNERMOST_TEMPLATE_ARGS (args); - /* If there are 0 or 1 parameter packs, we need to expand any argument - packs so that we can deduce a parameter pack from some non-packed args - followed by an argument pack, as in variadic85.C. If there are more - than that, we need to leave argument packs intact so the arguments are - assigned to the right parameter packs. This should only happen when - dealing with a nested class inside a partial specialization of a class - template, as in variadic92.C. */ - if (variadic_p <= 1) + /* If there are no parameters that follow a parameter pack, we need to + expand any argument packs so that we can deduce a parameter pack from + some non-packed args followed by an argument pack, as in variadic85.C. + If there are such parameters, we need to leave argument packs intact + so the arguments are assigned properly. This can happen when dealing + with a nested class inside a partial specialization of a class + template, as in variadic92.C, or when deducing a template parameter pack + from a sub-declarator, as in variadic114.C. */ + if (!post_variadic_parms) inner_args = expand_template_argument_pack (inner_args); nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; @@ -6574,7 +6578,7 @@ coerce_template_parms (tree parms, { if (variadic_p) { - --nparms; + nparms -= variadic_p; error ("wrong number of template arguments " "(%d, should be %d or more)", nargs, nparms); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1216d41ff43..ea0fc853f18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-19 Jason Merrill + + PR c++/49785 + * g++.dg/cpp0x/variadic114.C: New. + 2011-07-19 Tobias Burnus * gfortran.dg/coarray_args_1.f90: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic114.C b/gcc/testsuite/g++.dg/cpp0x/variadic114.C new file mode 100644 index 00000000000..3ffede5c507 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic114.C @@ -0,0 +1,27 @@ +// PR c++/49785 +// { dg-options -std=c++0x } + +template struct B { }; +template class A; + +template +struct A : public B +{ + struct C {}; + template A (D, C = C ()) { } + R operator () (...); +}; + +template +auto operator >> (A , T)->A +{ + []() {}; +} + +int +main () +{ + A a = [](int, int) {}; + auto b = []{}; + (a >> b) (3, 5); +} -- 2.30.2