diff options
author | Jason Merrill <jason@redhat.com> | 2019-01-29 21:43:04 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-01-29 21:43:04 -0500 |
commit | 538a530848375deb14495fae5a5ccf5ae5daedba (patch) | |
tree | 2014ffc7cf9d736a2f0e7a17bddbaa3c9087d660 /gcc/cp/lambda.c | |
parent | dca2770bc073353e621e426d4803b8ea16382b5a (diff) | |
download | gcc-538a530848375deb14495fae5a5ccf5ae5daedba.zip gcc-538a530848375deb14495fae5a5ccf5ae5daedba.tar.gz gcc-538a530848375deb14495fae5a5ccf5ae5daedba.tar.bz2 |
PR c++/86943 - wrong code converting lambda to function pointer.
In this PR, instantiating the static thunk returned from the generic lambda
conversion function template was using normal overload resolution, which
meant calling an extra constructor when forwarding its argument. Fixed by
special-casing thunk calls significantly more.
* lambda.c (maybe_add_lambda_conv_op): Use a template-id in the
call. Only forward parms for decltype.
* pt.c (tsubst_copy_and_build) [CALL_EXPR]: Handle CALL_FROM_THUNK_P
specially.
* typeck.c (check_return_expr): Don't mess with a thunk call.
From-SVN: r268377
Diffstat (limited to 'gcc/cp/lambda.c')
-rw-r--r-- | gcc/cp/lambda.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 6e6db1f..bc64a41 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -1095,8 +1095,10 @@ maybe_add_lambda_conv_op (tree type) implementation of the conversion operator. */ tree instance = cp_build_fold_indirect_ref (thisarg); - tree objfn = build_min (COMPONENT_REF, NULL_TREE, - instance, DECL_NAME (callop), NULL_TREE); + tree objfn = lookup_template_function (DECL_NAME (callop), + DECL_TI_ARGS (callop)); + objfn = build_min (COMPONENT_REF, NULL_TREE, + instance, objfn, NULL_TREE); int nargs = list_length (DECL_ARGUMENTS (callop)) - 1; call = prepare_op_call (objfn, nargs); @@ -1137,18 +1139,21 @@ maybe_add_lambda_conv_op (tree type) if (generic_lambda_p) { - /* Avoid capturing variables in this context. */ - ++cp_unevaluated_operand; - tree a = forward_parm (tgt); - --cp_unevaluated_operand; - + tree a = tgt; + if (DECL_PACK_P (tgt)) + { + a = make_pack_expansion (a); + PACK_EXPANSION_LOCAL_P (a) = true; + } 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; + if (decltype_call) + { + /* Avoid capturing variables in this context. */ + ++cp_unevaluated_operand; + CALL_EXPR_ARG (decltype_call, ix) = forward_parm (tgt); + --cp_unevaluated_operand; + } ++ix; } |