From bd28a34f33a84524d8c61fbf23d88d1158c579a7 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 25 Feb 2016 10:23:47 -0500 Subject: [PATCH] re PR c++/69842 (Parameter deduction in polymorphic lambdas) PR c++/69842 * method.c (forward_parm): Handle parameter packs. * lambda.c (maybe_add_lambda_conv_op): Use it for them. From-SVN: r233719 --- gcc/cp/ChangeLog | 4 +++ gcc/cp/lambda.c | 30 ++++++++----------- gcc/cp/method.c | 9 ++++-- .../g++.dg/cpp1y/lambda-generic-variadic4.C | 20 +++++++++++++ 4 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 97296e4d2224..ea4389d475a7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-02-25 Jason Merrill + PR c++/69842 + * method.c (forward_parm): Handle parameter packs. + * lambda.c (maybe_add_lambda_conv_op): Use it for them. + PR c++/67364 * constexpr.c (cxx_eval_component_reference): Don't complain about unevaluated empty classes. diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 296c6f7ecf2e..cdc11febcffa 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "tree-iterator.h" #include "toplev.h" +#include "gimplify.h" /* Constructor for a lambda expression. */ @@ -952,23 +953,18 @@ maybe_add_lambda_conv_op (tree type) if (generic_lambda_p) { - if (DECL_PACK_P (tgt)) - { - tree a = make_pack_expansion (tgt); - if (decltype_call) - CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); - PACK_EXPANSION_LOCAL_P (a) = true; - CALL_EXPR_ARG (call, ix) = a; - } - else - { - ++processing_template_decl; - tree a = forward_parm (tgt); - --processing_template_decl; - CALL_EXPR_ARG (call, ix) = a; - if (decltype_call) - CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); - } + ++processing_template_decl; + tree a = forward_parm (tgt); + --processing_template_decl; + + CALL_EXPR_ARG (call, ix) = a; + if (decltype_call) + CALL_EXPR_ARG (decltype_call, ix) = unshare_expr (a); + + if (PACK_EXPANSION_P (a)) + /* Set this after unsharing so it's not in decltype_call. */ + PACK_EXPANSION_LOCAL_P (a) = true; + ++ix; } else diff --git a/gcc/cp/method.c b/gcc/cp/method.c index f455b32e2a02..0235e6a9c22e 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -481,9 +481,12 @@ tree forward_parm (tree parm) { tree exp = convert_from_reference (parm); - if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE - || TYPE_REF_IS_RVALUE (TREE_TYPE (parm))) - exp = move (exp); + tree type = TREE_TYPE (parm); + if (DECL_PACK_P (parm)) + type = PACK_EXPANSION_PATTERN (type); + exp = build_static_cast (type, exp, tf_warning_or_error); + if (DECL_PACK_P (parm)) + exp = make_pack_expansion (exp); return exp; } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C new file mode 100644 index 000000000000..0b65f56fa873 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C @@ -0,0 +1,20 @@ +// PR c++/69842 +// { dg-do compile { target c++14 } } + +template struct assert_same; +template struct assert_same {}; + +template +void sink(T &&) +{ + assert_same a; +} + +int main() +{ + auto const g([](auto &&... _var) { + sink(static_cast(_var)...); + }); + + g(0); +} -- 2.47.2