From: Jason Merrill Date: Mon, 25 Jul 2016 19:16:16 +0000 (-0400) Subject: PR c++/71837 - pack expansion in init-capture X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=47265942fa55c8198ef712af8ee23c4700ca2dfb;p=gcc.git PR c++/71837 - pack expansion in init-capture * lambda.c (add_capture): Leave a pack expansion in a TREE_LIST. (build_lambda_object): Call build_x_compound_expr_from_list. * pt.c (tsubst) [DECLTYPE_TYPE]: Likewise. From-SVN: r238733 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9ae7e67eb21..87020979510 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2016-07-25 Jason Merrill + PR c++/71837 + * lambda.c (add_capture): Leave a pack expansion in a TREE_LIST. + (build_lambda_object): Call build_x_compound_expr_from_list. + * pt.c (tsubst) [DECLTYPE_TYPE]: Likewise. + PR c++/71833 PR c++/54440 * pt.c (coerce_template_parameter_pack): Fix logic for diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 4d6d80fe128..9bf8a560d02 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -79,6 +79,10 @@ build_lambda_object (tree lambda_expr) goto out; } + if (TREE_CODE (val) == TREE_LIST) + val = build_x_compound_expr_from_list (val, ELK_INIT, + tf_warning_or_error); + if (DECL_P (val)) mark_used (val); @@ -449,7 +453,9 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, variadic = true; } - if (TREE_CODE (initializer) == TREE_LIST) + if (TREE_CODE (initializer) == TREE_LIST + /* A pack expansion might end up with multiple elements. */ + && !PACK_EXPANSION_P (TREE_VALUE (initializer))) initializer = build_x_compound_expr_from_list (initializer, ELK_INIT, tf_warning_or_error); type = TREE_TYPE (initializer); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7dd6b25931d..97d50001b14 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13620,6 +13620,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /*function_p*/false, /*integral_constant_expression*/false); + if (DECLTYPE_FOR_INIT_CAPTURE (t)) + { + if (type == NULL_TREE) + { + if (complain & tf_error) + error ("empty initializer in lambda init-capture"); + type = error_mark_node; + } + else if (TREE_CODE (type) == TREE_LIST) + type = build_x_compound_expr_from_list (type, ELK_INIT, complain); + } + --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init15.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init15.C new file mode 100644 index 00000000000..8b3e5205aed --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init15.C @@ -0,0 +1,13 @@ +// PR c++/71837 +// { dg-do compile { target c++14 } } + +template < typename ... Ts > void f (Ts ... args) +{ + [ts (args ...)] { return ts; } (); +} + +int main () +{ + f (0); + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init15a.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init15a.C new file mode 100644 index 00000000000..166d650d4f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init15a.C @@ -0,0 +1,14 @@ +// PR c++/71837 +// { dg-do compile { target c++14 } } + +template < typename ... Ts > void f (Ts ... args) +{ + [ts (args ...)] { return ts; } (); // { dg-error "" } +} + +int main () +{ + f (); // { dg-message "required" } + f (1,2); // { dg-message "required" } + return 0; +}