diff options
author | Jason Merrill <jason@redhat.com> | 2020-04-22 02:27:54 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-04-22 02:27:55 -0400 |
commit | aedd04caa945260ea77fd22f29b77292f7dba72e (patch) | |
tree | d4cae8c16debd115b4d80c2e9f01f050c9b2c64b /gcc | |
parent | 587970215f4681def390e2a791aa3ba6adb65158 (diff) | |
download | gcc-aedd04caa945260ea77fd22f29b77292f7dba72e.zip gcc-aedd04caa945260ea77fd22f29b77292f7dba72e.tar.gz gcc-aedd04caa945260ea77fd22f29b77292f7dba72e.tar.bz2 |
c++: generic lambda forwarding function [PR94546]
While instantiating test(Plot) we partially instantiate the generic lambda.
We look at forward<T>(rest)... and see that it's just replacing parameter
packs with new parameter packs and tries to do a direct substitution. But
because register_parameter_specializations had built up a
NONTYPE_ARGUMENT_PACK around the new parameter pack, the substitution
failed. So let's not wrap it that way.
gcc/cp/ChangeLog
2020-04-22 Jason Merrill <jason@redhat.com>
PR c++/94546
* pt.c (register_parameter_specializations): If the instantiation is
still a parameter pack, don't wrap it in a NONTYPE_ARGUMENT_PACK.
(tsubst_pack_expansion, tsubst_expr): Adjust.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/lambda-generic-variadic20.C | 23 |
3 files changed, 40 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 640e494..4b6691a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2020-04-22 Jason Merrill <jason@redhat.com> + + PR c++/94546 + * pt.c (register_parameter_specializations): If the instantiation is + still a parameter pack, don't wrap it in a NONTYPE_ARGUMENT_PACK. + (tsubst_pack_expansion, tsubst_expr): Adjust. + 2020-04-22 Martin Sebor <msebor@redhat.com> Jason Merrill <jason@redhat.com> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7bf249c..2fe7b66 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12753,7 +12753,6 @@ 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; bool need_local_specializations = false; @@ -12833,19 +12832,15 @@ 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 (DECL_PACK_P (arg_pack)) + /* This argument pack isn't fully instantiated yet. */ + arg_pack = NULL_TREE; } else if (is_capture_proxy (parm_pack)) { arg_pack = retrieve_local_specialization (parm_pack); - if (argument_pack_element_is_expansion_p (arg_pack, 0)) - unsubstituted_fn_pack = true; + if (DECL_PACK_P (arg_pack)) + arg_pack = NULL_TREE; } else { @@ -12880,8 +12875,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) len = my_len; - else if (len != my_len - && !unsubstituted_fn_pack) + else if (len != my_len) { if (!(complain & tf_error)) /* Fail quietly. */; @@ -12904,10 +12898,6 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* We can't substitute for this parameter pack. We use a flag as well as the missing_level counter because function parameter packs don't have a level. */ - if (!(processing_template_decl || is_auto (parm_pack))) - { - gcc_unreachable (); - } gcc_assert (processing_template_decl || is_auto (parm_pack)); unsubstituted_packs = true; } @@ -17897,7 +17887,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, { inst = (retrieve_local_specialization (DECL_CAPTURED_VARIABLE (decl))); - gcc_assert (TREE_CODE (inst) == NONTYPE_ARGUMENT_PACK); + gcc_assert (TREE_CODE (inst) == NONTYPE_ARGUMENT_PACK + || DECL_PACK_P (inst)); } else inst = lookup_init_capture_pack (decl); @@ -25315,7 +25306,8 @@ register_parameter_specializations (tree pattern, tree inst) } for (; tmpl_parm; tmpl_parm = DECL_CHAIN (tmpl_parm)) { - if (!DECL_PACK_P (tmpl_parm)) + if (!DECL_PACK_P (tmpl_parm) + || (spec_parm && DECL_PACK_P (spec_parm))) { register_local_specialization (spec_parm, tmpl_parm); spec_parm = DECL_CHAIN (spec_parm); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-generic-variadic20.C b/gcc/testsuite/g++.dg/cpp2a/lambda-generic-variadic20.C new file mode 100644 index 0000000..3d69dbb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-generic-variadic20.C @@ -0,0 +1,23 @@ +// PR c++/94546 +// { dg-do compile { target c++2a } } + +template <class T> T&& forward(T&& t) { return static_cast<T&&>(t); } + +template <class X> +void test(X&& plot) +{ + // Note: For brevity, this lambda function is only + // defined, not called nor assigned to a variable. + // Doing those things won't fix the error. + [&]<class... T>(T&&... rest) + { + plot(forward<T>(rest)...); + }; +} +int main() +{ + auto Plot = [](auto&&...) + { + }; + test(Plot); +} |