From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <gentoo-commits+bounces-1679816-garchives=archives.gentoo.org@lists.gentoo.org>
Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits))
	(No client certificate requested)
	by finch.gentoo.org (Postfix) with ESMTPS id 92BF8158046
	for <garchives@archives.gentoo.org>; Sun, 13 Oct 2024 22:48:15 +0000 (UTC)
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id D36C8E0837;
	Sun, 13 Oct 2024 22:48:14 +0000 (UTC)
Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits))
	(No client certificate requested)
	by pigeon.gentoo.org (Postfix) with ESMTPS id B16E0E0837
	for <gentoo-commits@lists.gentoo.org>; Sun, 13 Oct 2024 22:48:14 +0000 (UTC)
Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits))
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id BB0DE34310E
	for <gentoo-commits@lists.gentoo.org>; Sun, 13 Oct 2024 22:48:13 +0000 (UTC)
Received: from localhost.localdomain (localhost [IPv6:::1])
	by oystercatcher.gentoo.org (Postfix) with ESMTP id 5754FAE7
	for <gentoo-commits@lists.gentoo.org>; Sun, 13 Oct 2024 22:48:12 +0000 (UTC)
From: "Sam James" <sam@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: 8bit
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Sam James" <sam@gentoo.org>
Message-ID: <1728859641.b4a852b00ffc7c9436d15867d602c28837c97758.sam@gentoo>
Subject: [gentoo-commits] proj/gcc-patches:master commit in: 15.0.0/gentoo/
X-VCS-Repository: proj/gcc-patches
X-VCS-Files: 15.0.0/gentoo/70_all_PR116506-coro.patch 15.0.0/gentoo/71_all_PR116914-coro.patch 15.0.0/gentoo/README.history
X-VCS-Directories: 15.0.0/gentoo/
X-VCS-Committer: sam
X-VCS-Committer-Name: Sam James
X-VCS-Revision: b4a852b00ffc7c9436d15867d602c28837c97758
X-VCS-Branch: master
Date: Sun, 13 Oct 2024 22:48:12 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply
X-Archives-Salt: 271256d9-8ce6-435f-8312-c66843d8dc01
X-Archives-Hash: 9c616d657ee0ac9f942e40feb963d865

commit:     b4a852b00ffc7c9436d15867d602c28837c97758
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 13 22:47:21 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Oct 13 22:47:21 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=b4a852b0

15.0.0: add two coro patches

Bug: https://gcc.gnu.org/PR116506
Bug: https://gcc.gnu.org/PR116914
Closes: https://bugs.gentoo.org/941147
Closes: https://bugs.gentoo.org/941148
Signed-off-by: Sam James <sam <AT> gentoo.org>

 15.0.0/gentoo/70_all_PR116506-coro.patch | 295 +++++++++++++++++++++++++++++++
 15.0.0/gentoo/71_all_PR116914-coro.patch |  51 ++++++
 15.0.0/gentoo/README.history             |   5 +
 3 files changed, 351 insertions(+)

diff --git a/15.0.0/gentoo/70_all_PR116506-coro.patch b/15.0.0/gentoo/70_all_PR116506-coro.patch
new file mode 100644
index 0000000..4e670fc
--- /dev/null
+++ b/15.0.0/gentoo/70_all_PR116506-coro.patch
@@ -0,0 +1,295 @@
+From 06475fcc5b72fdb9b24e7e39703942e1e3f2f0d5 Mon Sep 17 00:00:00 2001
+From: Iain Sandoe <iain@sandoe.co.uk>
+Date: Thu, 29 Aug 2024 11:18:24 +0100
+Subject: [PATCH] c++, coroutines: Fix awaiter var creation [PR116506].
+
+Awaiters always need to have a coroutine state frame copy since
+they persist across potential supensions.  It simplifies the later
+analysis considerably to assign these early which we do when
+building co_await expressions.
+
+The cleanups in r15-3146-g47dbd69b1, unfortunately elided some of
+processing used to cater for cases where the var created from an
+xvalue, or is a pointer/reference type.
+
+Corrected thus.
+
+	PR c++/116506
+	PR c++/116880
+
+gcc/cp/ChangeLog:
+
+	* coroutines.cc (build_co_await): Ensure that xvalues are
+	materialised.  Handle references/pointer values in awaiter
+	access expressions.
+
+gcc/testsuite/ChangeLog:
+
+	* g++.dg/coroutines/pr116506.C: New test.
+	* g++.dg/coroutines/pr116880.C: New test.
+
+Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
+---
+ gcc/cp/coroutines.cc                       | 82 +++++++++++++++++-----
+ gcc/testsuite/g++.dg/coroutines/pr116506.C | 53 ++++++++++++++
+ gcc/testsuite/g++.dg/coroutines/pr116880.C | 36 ++++++++++
+ 3 files changed, 154 insertions(+), 17 deletions(-)
+ create mode 100644 gcc/testsuite/g++.dg/coroutines/pr116506.C
+ create mode 100644 gcc/testsuite/g++.dg/coroutines/pr116880.C
+
+diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
+index 86a5ac8999a..ba6ee41a4e7 100644
+--- a/gcc/cp/coroutines.cc
++++ b/gcc/cp/coroutines.cc
+@@ -1071,6 +1071,30 @@ build_template_co_await_expr (location_t kw, tree type, tree expr, tree kind)
+   return aw_expr;
+ }
+ 
++/* For a component ref that is not a pointer type, decide if we can use
++   this directly.  */
++static bool
++usable_component_ref (tree comp_ref)
++{
++  if (TREE_CODE (comp_ref) != COMPONENT_REF
++      || TREE_SIDE_EFFECTS (comp_ref))
++    return false;
++
++  while (TREE_CODE (comp_ref) == COMPONENT_REF)
++    {
++      comp_ref = TREE_OPERAND (comp_ref, 0);
++      STRIP_NOPS (comp_ref);
++      /* x-> */
++      if (INDIRECT_REF_P (comp_ref))
++	return false;
++      /* operator-> */
++      if (TREE_CODE (comp_ref) == CALL_EXPR)
++	return false;
++      STRIP_NOPS (comp_ref);
++    }
++  gcc_checking_assert (VAR_P (comp_ref) || TREE_CODE (comp_ref) == PARM_DECL);
++  return true;
++}
+ 
+ /*  This performs [expr.await] bullet 3.3 and validates the interface obtained.
+     It is also used to build the initial and final suspend points.
+@@ -1133,13 +1157,12 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+   if (o_type && !VOID_TYPE_P (o_type))
+     o_type = complete_type_or_else (o_type, o);
+ 
+-  if (!o_type)
++  if (!o_type || o_type == error_mark_node)
+     return error_mark_node;
+ 
+   if (TREE_CODE (o_type) != RECORD_TYPE)
+     {
+-      error_at (loc, "awaitable type %qT is not a structure",
+-		o_type);
++      error_at (loc, "awaitable type %qT is not a structure", o_type);
+       return error_mark_node;
+     }
+ 
+@@ -1165,20 +1188,47 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+   if (!glvalue_p (o))
+     o = get_target_expr (o, tf_warning_or_error);
+ 
+-  tree e_proxy = o;
+-  if (glvalue_p (o))
++  /* We know that we need a coroutine state frame variable for the awaiter,
++     since it must persist across suspension; so where one is needed, build
++     it now.  */
++  tree e_proxy = STRIP_NOPS (o);
++  if (INDIRECT_REF_P (e_proxy))
++    e_proxy = TREE_OPERAND (e_proxy, 0);
++  o_type = TREE_TYPE (e_proxy);
++  bool is_ptr = TYPE_PTR_P (o_type);
++  if (!is_ptr
++      && (TREE_CODE (e_proxy) == PARM_DECL
++	  || usable_component_ref (e_proxy)
++	  || (VAR_P (e_proxy) && !is_local_temp (e_proxy))))
+     o = NULL_TREE; /* Use the existing entity.  */
+-  else /* We need to materialise it.  */
++  else /* We need a non-temp var.  */
+     {
+-      e_proxy = get_awaitable_var (suspend_kind, o_type);
+-      o = cp_build_init_expr (loc, e_proxy, o);
+-      e_proxy = convert_from_reference (e_proxy);
++      tree p_type = o_type;
++      tree o_a = o;
++      if (lvalue_p (o) && !TREE_SIDE_EFFECTS (o))
++	{
++	  if (is_ptr)
++	    p_type = TREE_TYPE (p_type);
++	  p_type = cp_build_reference_type (p_type, false);
++	  o_a = build_address (o);
++	}
++      if (INDIRECT_REF_P (o_a))
++	o_a = TREE_OPERAND (o_a, 0);
++      e_proxy = get_awaitable_var (suspend_kind, p_type);
++      o = cp_build_init_expr (loc, e_proxy, o_a);
+     }
+ 
++  /* Build an expression for the object that will be used to call the awaitable
++     methods.  */
++  tree e_object = convert_from_reference (e_proxy);
++  if (TYPE_PTR_P (TREE_TYPE (e_object)))
++    e_object = cp_build_indirect_ref (input_location, e_object, RO_UNARY_STAR,
++				      tf_warning_or_error);
++
+   /* I suppose we could check that this is contextually convertible to bool.  */
+   tree awrd_func = NULL_TREE;
+   tree awrd_call
+-    = build_new_method_call (e_proxy, awrd_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
++    = build_new_method_call (e_object, awrd_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
+ 			     &awrd_func, tf_warning_or_error);
+ 
+   if (!awrd_func || !awrd_call || awrd_call == error_mark_node)
+@@ -1192,7 +1242,7 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+   tree h_proxy = get_coroutine_self_handle_proxy (current_function_decl);
+   vec<tree, va_gc> *args = make_tree_vector_single (h_proxy);
+   tree awsp_call
+-    = build_new_method_call (e_proxy, awsp_meth, &args, NULL_TREE,
++    = build_new_method_call (e_object, awsp_meth, &args, NULL_TREE,
+ 			     LOOKUP_NORMAL, &awsp_func, tf_warning_or_error);
+ 
+   release_tree_vector (args);
+@@ -1224,7 +1274,7 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+   /* Finally, the type of e.await_resume() is the co_await's type.  */
+   tree awrs_func = NULL_TREE;
+   tree awrs_call
+-    = build_new_method_call (e_proxy, awrs_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
++    = build_new_method_call (e_object, awrs_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
+ 			     &awrs_func, tf_warning_or_error);
+ 
+   if (!awrs_func || !awrs_call || awrs_call == error_mark_node)
+@@ -1238,7 +1288,7 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+ 	return error_mark_node;
+       if (coro_diagnose_throwing_fn (awrs_func))
+ 	return error_mark_node;
+-      if (tree dummy = cxx_maybe_build_cleanup (e_proxy, tf_none))
++      if (tree dummy = cxx_maybe_build_cleanup (e_object, tf_none))
+ 	{
+ 	  if (CONVERT_EXPR_P (dummy))
+ 	    dummy = TREE_OPERAND (dummy, 0);
+@@ -1249,7 +1299,8 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+     }
+ 
+   /* We now have three call expressions, in terms of the promise, handle and
+-     'e' proxies.  Save them in the await expression for later expansion.  */
++     'e' proxy expression.  Save them in the await expression for later
++     expansion.  */
+ 
+   tree awaiter_calls = make_tree_vec (3);
+   TREE_VEC_ELT (awaiter_calls, 0) = awrd_call; /* await_ready().  */
+@@ -1262,9 +1313,6 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
+     }
+   TREE_VEC_ELT (awaiter_calls, 2) = awrs_call; /* await_resume().  */
+ 
+-  if (REFERENCE_REF_P (e_proxy))
+-    e_proxy = TREE_OPERAND (e_proxy, 0);
+-
+   tree awrs_type = TREE_TYPE (TREE_TYPE (awrs_func));
+   tree suspend_kind_cst = build_int_cst (integer_type_node,
+ 					 (int) suspend_kind);
+diff --git a/gcc/testsuite/g++.dg/coroutines/pr116506.C b/gcc/testsuite/g++.dg/coroutines/pr116506.C
+new file mode 100644
+index 00000000000..57a6e360566
+--- /dev/null
++++ b/gcc/testsuite/g++.dg/coroutines/pr116506.C
+@@ -0,0 +1,53 @@
++// { dg-do run }
++// { dg-additional-options "-fno-exceptions" }
++                                                       
++#include <coroutine>
++
++bool g_too_early = true;
++std::coroutine_handle<> g_handle;
++
++struct Awaiter {
++    Awaiter() {}
++    ~Awaiter() {
++        if (g_too_early) {
++            __builtin_abort ();
++        }
++    }
++
++    bool await_ready() { return false; }
++    void await_suspend(std::coroutine_handle<> handle) {
++        g_handle = handle;
++    }
++
++    void await_resume() {}
++};
++
++struct SuspendNever {
++    bool await_ready() noexcept { return true; }
++    void await_suspend(std::coroutine_handle<>) noexcept {}
++    void await_resume() noexcept {}
++};
++
++struct Coroutine {
++    struct promise_type {
++        Coroutine get_return_object() { return {}; }
++        SuspendNever initial_suspend() { return {}; }
++        SuspendNever final_suspend() noexcept { return {}; }
++        void return_void() {}
++        void unhandled_exception() {}
++
++        Awaiter&& await_transform(Awaiter&& u) {
++            return static_cast<Awaiter&&>(u);
++        }
++    };
++};
++
++Coroutine foo() {
++    co_await Awaiter{};
++}
++
++int main() {
++    foo();
++    g_too_early = false;
++    g_handle.destroy();
++}
+diff --git a/gcc/testsuite/g++.dg/coroutines/pr116880.C b/gcc/testsuite/g++.dg/coroutines/pr116880.C
+new file mode 100644
+index 00000000000..f0db6a26044
+--- /dev/null
++++ b/gcc/testsuite/g++.dg/coroutines/pr116880.C
+@@ -0,0 +1,36 @@
++#include <coroutine>
++
++struct promise_type;
++using handle_type = std::coroutine_handle<promise_type>;
++
++struct Co {
++    handle_type handle;
++    using promise_type = ::promise_type;
++
++    explicit Co(handle_type handle) : handle(handle) {}
++
++    bool await_ready() { return false; }
++    std::coroutine_handle<> await_suspend(handle_type handle);
++    void await_resume() {}
++};
++
++struct Done {};
++
++struct promise_type {
++    Co get_return_object();
++
++    std::suspend_always initial_suspend() { return {}; };
++    std::suspend_always final_suspend() noexcept { return {}; };
++    void return_value(Done) {}
++    void return_value(Co&&);
++    void unhandled_exception() { throw; };
++    Co&& await_transform(Co&& co) { return static_cast<Co&&>(co); }
++};
++
++Co tryToRun();
++
++Co init()
++{
++    co_await tryToRun();
++    co_return Done{};
++}
+-- 
+2.39.2 (Apple Git-143)

diff --git a/15.0.0/gentoo/71_all_PR116914-coro.patch b/15.0.0/gentoo/71_all_PR116914-coro.patch
new file mode 100644
index 0000000..100d2bb
--- /dev/null
+++ b/15.0.0/gentoo/71_all_PR116914-coro.patch
@@ -0,0 +1,51 @@
+From 1035866a75b27bb2cac49bac1070877d95f7d3c0 Mon Sep 17 00:00:00 2001
+From: Iain Sandoe <iain@sandoe.co.uk>
+Date: Sun, 29 Sep 2024 10:04:39 +0100
+Subject: [PATCH] c++, coroutines: stmt expressions some progress
+
+---
+ gcc/cp/coroutines.cc | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
+index af8798b04ba..94bfa6ac450 100644
+--- a/gcc/cp/coroutines.cc
++++ b/gcc/cp/coroutines.cc
+@@ -2131,6 +2131,14 @@ await_statement_expander (tree *stmt, int *do_subtree, void *d)
+     }
+   else if (EXPR_P (*stmt))
+     {
++      /* Look for ({}) at the top level - just recurse into these.  */
++      if (TREE_CODE (*stmt) == EXPR_STMT)
++	{
++	  tree inner = EXPR_STMT_EXPR (*stmt);
++	  if (TREE_CODE (inner) == STATEMENT_LIST
++	      || TREE_CODE (inner) == BIND_EXPR)
++	    return NULL_TREE; // process contents
++	}
+       process_one_statement (stmt, d);
+       *do_subtree = 0; /* Done subtrees.  */
+     }
+@@ -3860,6 +3868,20 @@ await_statement_walker (tree *stmt, int *do_subtree, void *d)
+       if (!(cp_walk_tree (stmt, find_any_await, &await_ptr, &visited)))
+ 	return NULL_TREE; /* Nothing special to do here.  */
+ 
++      /* Handle statement expressions.  */
++      if (TREE_CODE (expr) == EXPR_STMT)
++	{
++	  tree inner = EXPR_STMT_EXPR (expr);
++	  if (TREE_CODE (inner) == STATEMENT_LIST
++	      || TREE_CODE (inner) == BIND_EXPR)
++	    {
++	      res = cp_walk_tree (&EXPR_STMT_EXPR (expr),
++				  await_statement_walker, d, NULL);
++	      *do_subtree = 0;
++	      return res;
++	    }
++	}
++
+       visited.empty ();
+       awpts->saw_awaits = 0;
+       hash_set<tree> truth_aoif_to_expand;
+-- 
+2.39.2 (Apple Git-143)

diff --git a/15.0.0/gentoo/README.history b/15.0.0/gentoo/README.history
index a6954a6..073283d 100644
--- a/15.0.0/gentoo/README.history
+++ b/15.0.0/gentoo/README.history
@@ -1,3 +1,8 @@
+16	13 October 2024
+
+	+ 70_all_PR116506-coro.patch
+	+ 71_all_PR116914-coro.patch
+
 15	7 October 2024
 
 	- 71_all_c-Allow-references-to-internal-linkage-vars-in-C-11-.patch