diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2021-10-02 12:44:01 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2021-10-03 20:41:59 +0100 |
commit | 0ee1ab15c237ffb50be1a5ce9c5e542b16df4d12 (patch) | |
tree | dc2bda9d2a7656bff68d73c083446387ea3befaa /gcc | |
parent | 8fbe1b18ed090a026d08f0b0e5f8cd56d652125d (diff) | |
download | gcc-0ee1ab15c237ffb50be1a5ce9c5e542b16df4d12.zip gcc-0ee1ab15c237ffb50be1a5ce9c5e542b16df4d12.tar.gz gcc-0ee1ab15c237ffb50be1a5ce9c5e542b16df4d12.tar.bz2 |
coroutines: Look through NOPs for awaiter variables [PR 99575].
There was a missing STRIP_NOPS which meant that, in some cases,
an awaiter variable could be hidden by a view-convert-expr.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
PR c++/99575
gcc/cp/ChangeLog:
* coroutines.cc (build_co_await): Strip NOPs from
candidate awaiter expressions before testing to see
if they need a temporary.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/pr99575.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/coroutines.cc | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr99575.C | 35 |
2 files changed, 36 insertions, 0 deletions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 2f45575..876a146 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1008,6 +1008,7 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind) } /* Only build a temporary if we need it. */ + STRIP_NOPS (e_proxy); if (TREE_CODE (e_proxy) == PARM_DECL || (VAR_P (e_proxy) && !is_local_temp (e_proxy))) { diff --git a/gcc/testsuite/g++.dg/coroutines/pr99575.C b/gcc/testsuite/g++.dg/coroutines/pr99575.C new file mode 100644 index 0000000..d5f86c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr99575.C @@ -0,0 +1,35 @@ + +#include <coroutine> + +class Task { + public: + struct promise_type { + Task get_return_object() { return Task{}; } + std::suspend_always initial_suspend() { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() {} + void return_void() {} + }; + + bool await_ready() const { return false; } + void await_suspend(std::coroutine_handle<void> continuation) {} + void await_resume() {} +}; + +class NonMoveableTask { + public: + NonMoveableTask() = default; + NonMoveableTask(const NonMoveableTask&) = delete; + NonMoveableTask(NonMoveableTask&&) = delete; + + NonMoveableTask& operator=(const NonMoveableTask&) = delete; + NonMoveableTask& operator=(NonMoveableTask&& other) = delete; + + bool await_ready() const { return false; } + void await_suspend(std::coroutine_handle<void>) {} + void await_resume() {} +}; + +Task Foo(NonMoveableTask* task) { co_await* task; } + +int main() {} |