public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r9-9549] c++: lambda pack init-capture within generic lambda
@ 2021-05-21 14:50 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2021-05-21 14:50 UTC (permalink / raw)
  To: gcc-cvs

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);
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-05-21 14:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-21 14:50 [gcc r9-9549] c++: lambda pack init-capture within generic lambda Jason Merrill

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).