aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArsen Arsenović <arsen@aarsen.me>2024-07-23 13:01:03 +0200
committerArsen Arsenović <arsen@gcc.gnu.org>2024-07-23 16:23:20 +0200
commit826134760c49518d97769c8bb7ecbc264b78cac9 (patch)
treea4cc7b8ecb9320873abb1a78ac006b16aa193c7d
parentb95c82d60c8c88f6346c5602f2e22a4531afe47c (diff)
downloadgcc-826134760c49518d97769c8bb7ecbc264b78cac9.zip
gcc-826134760c49518d97769c8bb7ecbc264b78cac9.tar.gz
gcc-826134760c49518d97769c8bb7ecbc264b78cac9.tar.bz2
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 <iain@sandoe.co.uk>
-rw-r--r--gcc/testsuite/g++.dg/coroutines/torture/pr103953.C75
1 files changed, 75 insertions, 0 deletions
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 0000000..da559f8
--- /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 ();
+}