From: Jason Merrill Date: Wed, 17 Feb 2016 20:45:15 +0000 (-0500) Subject: re PR c++/69842 (Parameter deduction in polymorphic lambdas) X-Git-Tag: basepoints/gcc-7~890 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f02dd56f5f50238244a729bde63387d42c36d63;p=thirdparty%2Fgcc.git re PR c++/69842 (Parameter deduction in polymorphic lambdas) PR c++/69842 * method.c (forward_parm): Split out from... (add_one_base_init): ...here. * lambda.c (maybe_add_lambda_conv_op): Use it. From-SVN: r233506 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b76f85d8f365..c02ffac46322 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-02-17 Jason Merrill + + PR c++/69842 + * method.c (forward_parm): Split out from... + (add_one_base_init): ...here. + * lambda.c (maybe_add_lambda_conv_op): Use it. + 2016-02-16 Jason Merrill PR c++/10200 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3b91089f50d0..7800ae8316df 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6013,6 +6013,7 @@ extern tree make_thunk (tree, bool, tree, tree); extern void finish_thunk (tree); extern void use_thunk (tree, bool); extern bool trivial_fn_p (tree); +extern tree forward_parm (tree); extern bool is_trivially_xible (enum tree_code, tree, tree); extern tree get_defaulted_eh_spec (tree); extern tree unevaluated_noexcept_spec (void); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 93b192c46f17..296c6f7ecf2e 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -962,7 +962,9 @@ maybe_add_lambda_conv_op (tree type) } else { - tree a = convert_from_reference (tgt); + ++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); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index e358ebd1c8c0..f455b32e2a02 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -474,6 +474,19 @@ trivial_fn_p (tree fn) return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn)); } +/* PARM is a PARM_DECL for a function which we want to forward to another + function without changing its value category, a la std::forward. */ + +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); + return exp; +} + /* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO given the parameter or parameters PARM, possibly inherited constructor base INH, or move flag MOVE_P. */ @@ -494,10 +507,7 @@ add_one_base_init (tree binfo, tree parm, bool move_p, tree inh, init = NULL_TREE; for (; parm; parm = DECL_CHAIN (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 exp = forward_parm (parm); *p = build_tree_list (NULL_TREE, exp); p = &TREE_CHAIN (*p); } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv1.C new file mode 100644 index 000000000000..6569af4fc25e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv1.C @@ -0,0 +1,14 @@ +// PR c++/69842 +// { dg-do compile { target c++14 } } + +template struct same; +template struct same {}; + +int main() +{ + auto g = [](auto && _var) { + same(); + }; + + g(0); +}