[pushed] c++: coroutines and range for [PR118491]
Checks
Commit Message
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
@@ -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);
}
new file mode 100644
@@ -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.;
+ }
+}