https://gcc.gnu.org/g:826134760c49518d97769c8bb7ecbc264b78cac9

commit r15-2227-g826134760c49518d97769c8bb7ecbc264b78cac9
Author: Arsen Arsenović <ar...@aarsen.me>
Date:   Tue Jul 23 13:01:03 2024 +0200

    cp/coroutines: add a test for PR c++/103953
    
    This PR seems to have been fixed by a fix for a seemingly unrelated PR.
    Lets add a regression test to make sure it stays fixed.
    
    PR c++/103953 - Leak of coroutine return object
    
            PR c++/103953
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/coroutines/torture/pr103953.C: New test.
    
    Reviewed-by: Iain Sandoe <i...@sandoe.co.uk>

Diff:
---
 gcc/testsuite/g++.dg/coroutines/torture/pr103953.C | 75 ++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr103953.C 
b/gcc/testsuite/g++.dg/coroutines/torture/pr103953.C
new file mode 100644
index 000000000000..da559f8fa0d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/pr103953.C
@@ -0,0 +1,75 @@
+// { dg-do run }
+// https://gcc.gnu.org/PR103953
+#include <coroutine>
+#include <utility>
+
+static int ctor_dtor_count = 0;
+
+struct task {
+    struct promise_type;
+
+    using handle_type = std::coroutine_handle<promise_type>;
+
+    task(handle_type h) : handle(h) {
+        ctor_dtor_count++;
+    }
+    task(const task & t) : handle(t.handle) {
+        ctor_dtor_count++;
+    }
+    task(task && t) : handle(std::move(t.handle)) {
+        ctor_dtor_count++;
+    }
+    ~task() {
+       if (--ctor_dtor_count < 0)
+           __builtin_abort ();
+    }
+
+    struct promise_type {
+        auto get_return_object() {
+            return task{handle_type::from_promise(*this)};
+        }
+
+        auto initial_suspend() {
+            return std::suspend_always {};
+        }
+
+        auto unhandled_exception() {}
+
+        auto final_suspend() noexcept {
+            return std::suspend_always{};
+        }
+
+        void return_void() {}
+    };
+
+   handle_type handle;
+
+   void await_resume() {
+       handle.resume();
+   }
+
+   auto await_suspend(handle_type) {
+       return handle;
+   }
+
+   auto await_ready() {
+       return false;
+   }
+};
+
+int main() {
+    {
+       task coroutine_A = []() ->task {
+           co_return;
+       }();
+
+       task coroutine_B = [&coroutine_A]() ->task {
+           co_await coroutine_A;
+       }();
+
+       coroutine_B.handle.resume();
+    }
+
+    if (ctor_dtor_count != 0)
+       __builtin_abort ();
+}

Reply via email to