Regtested on x86_64-pc-linux-gnu.  OK for trunk?
---------- >8 ----------
In some scenarios, it is possible for the CFG cleanup to cause one of
the labels mentioned in CO_YIELD, which coro-early-expand-ifns intends
to remove, to become part of some statement.  As a result, when that
label is removed, the statement it became part of becomes invalid,
crashing the compiler.

There doesn't appear to be a reason to remove the labels (anymore, at
least), so let's not do that.

        PR c++/105104

gcc/ChangeLog:

        * coroutine-passes.cc (execute_early_expand_coro_ifns): Don't
        remove any labels.

gcc/testsuite/ChangeLog:

        * g++.dg/coroutines/torture/pr105104.C: New test.
---
 gcc/coroutine-passes.cc                       | 26 ------------
 .../g++.dg/coroutines/torture/pr105104.C      | 40 +++++++++++++++++++
 2 files changed, 40 insertions(+), 26 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/torture/pr105104.C

diff --git a/gcc/coroutine-passes.cc b/gcc/coroutine-passes.cc
index 9124ecae5916..0f8e24f8d551 100644
--- a/gcc/coroutine-passes.cc
+++ b/gcc/coroutine-passes.cc
@@ -294,9 +294,6 @@ execute_early_expand_coro_ifns (void)
   /* Some of the possible YIELD points will hopefully have been removed by
      earlier optimisations; record the ones that are still present.  */
   hash_map<int_hash<HOST_WIDE_INT, -1, -2>, tree> destinations;
-  /* Labels we added to carry the CFG changes, we need to remove these to
-     avoid confusing EH.  */
-  hash_set<tree> to_remove;
   /* List of dispatch points to update.  */
   auto_vec<gimple_stmt_iterator, 16> actor_worklist;
   basic_block bb;
@@ -384,8 +381,6 @@ execute_early_expand_coro_ifns (void)
                }
              else
                dst_dest = dst_tgt;
-             to_remove.add (res_tgt);
-             to_remove.add (dst_tgt);
              /* lose the co_yield.  */
              gsi_remove (&gsi, true);
              stmt = gsi_stmt (gsi); /* next. */
@@ -473,27 +468,6 @@ execute_early_expand_coro_ifns (void)
        }
     }
 
-  /* Remove the labels we inserted to map our hidden CFG, this
-     avoids confusing block merges when there are also EH labels.  */
-  FOR_EACH_BB_FN (bb, cfun)
-    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
-      {
-       gimple *stmt = gsi_stmt (gsi);
-       if (glabel *glab = dyn_cast<glabel *> (stmt))
-         {
-           tree rem = gimple_label_label (glab);
-           if (to_remove.contains (rem))
-             {
-               gsi_remove (&gsi, true);
-               to_remove.remove (rem);
-               continue; /* We already moved to the next insn.  */
-             }
-         }
-       else
-         break;
-       gsi_next (&gsi);
-      }
-
   /* Changed the CFG.  */
   todoflags |= TODO_cleanup_cfg;
   return todoflags;
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr105104.C 
b/gcc/testsuite/g++.dg/coroutines/torture/pr105104.C
new file mode 100644
index 000000000000..fcc783e3066d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr105104.C
@@ -0,0 +1,40 @@
+// https://gcc.gnu.org/PR105104
+// { dg-additional-options "-O" }
+
+#include <coroutine>
+
+// ICE during GIMPLE pass: coro-early-expand-ifs. final_awaiter::await_resume 
is
+// non-void, and optimizations are enabled.
+
+struct return_object
+{
+  struct promise_type
+  {
+    static constexpr std::suspend_always initial_suspend () noexcept
+    {
+      return {};
+    }
+
+    struct final_awaiter
+    {
+      static constexpr bool await_ready () noexcept { return false; }
+      static constexpr void await_suspend (std::coroutine_handle<>) noexcept {}
+      static constexpr int await_resume () noexcept { return {}; }
+    };
+    static constexpr final_awaiter final_suspend () noexcept { return {}; }
+
+    static void unhandled_exception () { throw; }
+
+    return_object get_return_object () { return {}; }
+
+    static constexpr void return_void () noexcept {}
+  };
+};
+
+return_object
+coroutine ()
+{
+  co_return;
+}
+
+return_object f = coroutine ();
-- 
2.46.0

Reply via email to