[pushed] c++: coroutines and range for [PR118491]

Message ID 20250203220053.3713955-1-jason@redhat.com
State New
Headers
Series [pushed] c++: coroutines and range for [PR118491] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Jason Merrill Feb. 3, 2025, 9:59 p.m. UTC
  Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

The implementation of extended range-for temporaries in r15-3840 confused
coroutines, because await_statement_walker and the like get confused by the
EXPR_STMT into thinking that the whole for-loop is a single expression
statement and try to process it accordingly.  Fixing this seems to be a
simple matter of dropping the EXPR_STMT.

	PR c++/116914
	PR c++/117231
	PR c++/118470
	PR c++/118491

gcc/cp/ChangeLog:

	* semantics.cc (finish_for_stmt): Don't wrap the result of
	pop_stmt_list in EXPR_STMT.

gcc/testsuite/ChangeLog:

	* g++.dg/coroutines/coro-range-for1.C: New test.
---
 gcc/cp/semantics.cc                           |  1 -
 .../g++.dg/coroutines/coro-range-for1.C       | 38 +++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/coro-range-for1.C


base-commit: f3a41e6cb5d70f0c94cc8273a118b8542fb5c2fa
  

Patch

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index ad9864c3a91..73b49174de4 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -1709,7 +1709,6 @@  finish_for_stmt (tree for_stmt)
     {
       tree stmt = pop_stmt_list (FOR_INIT_STMT (for_stmt));
       FOR_INIT_STMT (for_stmt) = NULL_TREE;
-      stmt = build_stmt (EXPR_LOCATION (for_stmt), EXPR_STMT, stmt);
       stmt = maybe_cleanup_point_expr_void (stmt);
       add_stmt (stmt);
     }
diff --git a/gcc/testsuite/g++.dg/coroutines/coro-range-for1.C b/gcc/testsuite/g++.dg/coroutines/coro-range-for1.C
new file mode 100644
index 00000000000..eaf4d19e62c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/coro-range-for1.C
@@ -0,0 +1,38 @@ 
+// PR c++/118491
+// { dg-do compile { target c++20 } }
+
+#include <coroutine>
+
+struct task {
+  struct promise_type {
+    task get_return_object() { return {}; }
+    std::suspend_always initial_suspend() { return {}; }
+    std::suspend_always final_suspend() noexcept { return {}; }
+    std::suspend_always yield_value(double value) { return {}; }
+    void unhandled_exception() { throw; }
+  };
+};
+
+task do_task() {
+  const int arr[]{1, 2, 3};
+
+  // No ICE if classic loop and not range-based one.
+  // for (auto i = 0; i < 10; ++i) {
+
+  // No ICE if these are moved out of the loop.
+  // auto x = std::suspend_always{};
+  // co_await x;
+
+  for (auto _ : arr) {
+    auto bar = std::suspend_always{};
+    co_await bar;
+
+    // Alternatively:
+    // auto bar = 42.;
+    // co_yield bar;
+
+    // No ICE if r-values:
+    // co_await std::suspend_always{};
+    // co_yield 42.;
+  }
+}