diff options
author | Arsen Arsenović <arsen@aarsen.me> | 2024-07-23 13:01:03 +0200 |
---|---|---|
committer | Arsen Arsenović <arsen@gcc.gnu.org> | 2024-07-23 16:23:20 +0200 |
commit | 826134760c49518d97769c8bb7ecbc264b78cac9 (patch) | |
tree | a4cc7b8ecb9320873abb1a78ac006b16aa193c7d /gcc | |
parent | b95c82d60c8c88f6346c5602f2e22a4531afe47c (diff) | |
download | gcc-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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/torture/pr103953.C | 75 |
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 (); +} |