From 018e9cb5e6050e03944f426e300a1227cbbba3e2 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 24 Jan 2018 10:20:53 -0500 Subject: [PATCH] PR c++/82249 - wrong mismatched pack length error. * pt.c (extract_fnparm_pack, tsubst_pack_expansion): Handle unsubstituted function parameter pack. From-SVN: r257018 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 21 ++++++++++++++++++--- .../g++.dg/cpp1y/lambda-generic-variadic7.C | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bc89041..2c499db 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-01-23 Jason Merrill + + PR c++/82249 - wrong mismatched pack length error. + * pt.c (extract_fnparm_pack, tsubst_pack_expansion): Handle + unsubstituted function parameter pack. + 2018-01-23 Paolo Carlini PR c++/83921 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d39b54e..abfdbd9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10961,7 +10961,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p) parmvec = make_tree_vec (len); spec_parm = *spec_p; for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) - TREE_VEC_ELT (parmvec, i) = spec_parm; + { + tree elt = spec_parm; + if (DECL_PACK_P (elt)) + elt = make_pack_expansion (elt); + TREE_VEC_ELT (parmvec, i) = elt; + } /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, parmvec); @@ -11414,6 +11419,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree pattern; tree pack, packs = NULL_TREE; bool unsubstituted_packs = false; + bool unsubstituted_fn_pack = false; int i, len = -1; tree result; hash_map *saved_local_specializations = NULL; @@ -11484,6 +11490,13 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, else arg_pack = make_fnparm_pack (arg_pack); } + else if (argument_pack_element_is_expansion_p (arg_pack, 0)) + /* This argument pack isn't fully instantiated yet. We set this + flag rather than clear arg_pack because we do want to do the + optimization below, and we don't want to substitute directly + into the pattern (as that would expose a NONTYPE_ARGUMENT_PACK + where it isn't expected). */ + unsubstituted_fn_pack = true; } else if (TREE_CODE (parm_pack) == FIELD_DECL) arg_pack = tsubst_copy (parm_pack, args, complain, in_decl); @@ -11521,7 +11534,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) len = my_len; - else if (len != my_len) + else if (len != my_len + && !unsubstituted_fn_pack) { if (!(complain & tf_error)) /* Fail quietly. */; @@ -11574,7 +11588,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* We cannot expand this expansion expression, because we don't have all of the argument packs we need. */ - if (use_pack_expansion_extra_args_p (packs, len, unsubstituted_packs)) + if (use_pack_expansion_extra_args_p (packs, len, (unsubstituted_packs + || unsubstituted_fn_pack))) { /* We got some full packs, but we can't substitute them in until we have values for all the packs. So remember these until then. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic7.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic7.C new file mode 100644 index 0000000..5c5af14 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic7.C @@ -0,0 +1,19 @@ +// PR c++/82249 +// { dg-do compile { target c++14 } } + +template T calc (T t, U u) { return t; } +template void sink(Ts...); + +template < typename ... Ds > +void f(Ds ...) { + [](auto ... n){ + sink (calc(n, Ds{}) ...); + }(Ds{} ...); +} + + +int main(){ + f(); // Wrong error + f(0, 0); // Wrong error + f(0); // ICE +} -- 2.7.4