From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id 40246385783A; Fri, 21 May 2021 14:50:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 40246385783A MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r9-9549] c++: lambda pack init-capture within generic lambda X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/releases/gcc-9 X-Git-Oldrev: 5b4cb06374890f2a190c9a989b569a9a15388445 X-Git-Newrev: 7168fb621b4442936d2a9429389a65f15043e5e4 Message-Id: <20210521145059.40246385783A@sourceware.org> Date: Fri, 21 May 2021 14:50:59 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 May 2021 14:50:59 -0000 https://gcc.gnu.org/g:7168fb621b4442936d2a9429389a65f15043e5e4 commit r9-9549-g7168fb621b4442936d2a9429389a65f15043e5e4 Author: Jason Merrill Date: Fri Apr 2 11:05:46 2021 -0400 c++: lambda pack init-capture within generic lambda We represent the type of a pack init-capture as auto... with packs from the initializer stuck into PACK_EXPANSION_PARAMETER_PACKS so that expanding it produces the right number of elements. But when partially instantiating the auto..., we were changing PACK_EXPANSION_PARAMETER_PACKS to refer to only the auto itself. Fixed thus. gcc/cp/ChangeLog: PR c++/97938 * cp-tree.h (PACK_EXPANSION_AUTO_P): New. * lambda.c (add_capture): Set it. * pt.c (tsubst_pack_expansion): Handle it. gcc/testsuite/ChangeLog: PR c++/97938 * g++.dg/cpp2a/lambda-pack-init6.C: New test. Diff: --- gcc/cp/cp-tree.h | 4 ++++ gcc/cp/lambda.c | 7 +++++-- gcc/cp/pt.c | 19 ++++++++++++++---- gcc/testsuite/g++.dg/cpp2a/lambda-pack-init6.C | 27 ++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index be291e99ce6..f1106dd9188 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -443,6 +443,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT) LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR) IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR) + PACK_EXPANSION_AUTO_P (in *_PACK_EXPANSION) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) @@ -3622,6 +3623,9 @@ struct GTY(()) lang_decl { /* True iff this pack expansion is for sizeof.... */ #define PACK_EXPANSION_SIZEOF_P(NODE) TREE_LANG_FLAG_1 (NODE) +/* True iff this pack expansion is for auto... in lambda init-capture. */ +#define PACK_EXPANSION_AUTO_P(NODE) TREE_LANG_FLAG_2 (NODE) + /* True iff the wildcard can match a template parameter pack. */ #define WILDCARD_PACK_P(NODE) TREE_LANG_FLAG_0 (NODE) diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 38e9b2f8a5f..1ee75814004 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -608,8 +608,11 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, parameter pack in this context. We will want as many fields as we have elements in the expansion of the initializer, so use its packs instead. */ - PACK_EXPANSION_PARAMETER_PACKS (type) - = uses_parameter_packs (initializer); + { + PACK_EXPANSION_PARAMETER_PACKS (type) + = uses_parameter_packs (initializer); + PACK_EXPANSION_AUTO_P (type) = true; + } } /* Make member variable. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 20bc198efac..612557bb717 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12447,12 +12447,23 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, pattern and return a PACK_EXPANSION_*. The caller will need to deal with that. */ if (TREE_CODE (t) == EXPR_PACK_EXPANSION) - t = tsubst_expr (pattern, args, complain, in_decl, + result = tsubst_expr (pattern, args, complain, in_decl, /*integral_constant_expression_p=*/false); else - t = tsubst (pattern, args, complain, in_decl); - t = make_pack_expansion (t, complain); - return t; + result = tsubst (pattern, args, complain, in_decl); + result = make_pack_expansion (result, complain); + if (PACK_EXPANSION_AUTO_P (t)) + { + /* This is a fake auto... pack expansion created in add_capture with + _PACKS that don't appear in the pattern. Copy one over. */ + packs = PACK_EXPANSION_PARAMETER_PACKS (t); + pack = retrieve_local_specialization (TREE_VALUE (packs)); + gcc_checking_assert (DECL_PACK_P (pack)); + PACK_EXPANSION_PARAMETER_PACKS (result) + = build_tree_list (NULL_TREE, pack); + PACK_EXPANSION_AUTO_P (result) = true; + } + return result; } gcc_assert (len >= 0); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init6.C b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init6.C new file mode 100644 index 00000000000..3ee500ed999 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init6.C @@ -0,0 +1,27 @@ +// PR c++/97938 +// { dg-do compile { target c++20 } } + +template +int sink(Args&&... args) { return 2; } + +auto fwd1(const auto&&... ts1) { + return + [...ts1 = ts1] { + return sink(ts1...); + }(); +} + +template +auto fwd2(const T1& t1) { + return + [] (auto&&... ts1) { + return + [...ts1 = ts1] { + return sink(ts1...); + }(); + }(); +} + +int main() { + return fwd1() + fwd2(1); +}