public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jason Merrill <jason@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r9-9549] c++: lambda pack init-capture within generic lambda Date: Fri, 21 May 2021 14:50:59 +0000 (GMT) [thread overview] Message-ID: <20210521145059.40246385783A@sourceware.org> (raw) https://gcc.gnu.org/g:7168fb621b4442936d2a9429389a65f15043e5e4 commit r9-9549-g7168fb621b4442936d2a9429389a65f15043e5e4 Author: Jason Merrill <jason@redhat.com> 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 <typename... Args> +int sink(Args&&... args) { return 2; } + +auto fwd1(const auto&&... ts1) { + return + [...ts1 = ts1] { + return sink(ts1...); + }(); +} + +template <typename T1> +auto fwd2(const T1& t1) { + return + [] (auto&&... ts1) { + return + [...ts1 = ts1] { + return sink(ts1...); + }(); + }(); +} + +int main() { + return fwd1() + fwd2(1); +}
reply other threads:[~2021-05-21 14:50 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210521145059.40246385783A@sourceware.org \ --to=jason@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).