c++: co_await and move-only type [PR105406]
[official-gcc.git] / gcc / testsuite / g++.dg / coroutines / co-await-moveonly1.C
blobe2831c104bf8cea205558214d815a62f05d6b7fb
1 // PR c++/105406
2 // { dg-do compile { target c++20 } }
4 #include <coroutine>
5 #include <exception>
7 // A move-only awaitable
8 class MoveOnlyAwaitable {
9 public:
10     MoveOnlyAwaitable() = default;
11     MoveOnlyAwaitable(MoveOnlyAwaitable &&) = default;
12     MoveOnlyAwaitable &operator=(MoveOnlyAwaitable &&) = default;
14     MoveOnlyAwaitable(const MoveOnlyAwaitable &) = delete;
15     MoveOnlyAwaitable &operator=(const MoveOnlyAwaitable &) = delete;
17     bool await_ready() const noexcept { return false; }
18     void await_suspend(std::coroutine_handle<>) noexcept {}
19     void await_resume() {}
22 struct task {
23     struct promise_type {
24         auto initial_suspend() const { return std::suspend_never{}; }
25         auto final_suspend() const noexcept { return std::suspend_never(); }
26         auto get_return_object() { return task{}; }
27         void return_void() {}
28         void unhandled_exception() {}
30         template<typename T>
31         T &&await_transform(T &&t) {
32             return static_cast<T &&>(t);
33         }
36     };
38     bool await_ready() const { return false; }
39     void await_suspend(std::coroutine_handle<> awaiter) {}
40     void await_resume() {}
43 task myCoroutine() {
44     // GCC: OK
45     // clang: OK
46     {
47         co_await MoveOnlyAwaitable();
48     }
49     // GCC: OK
50     // clang: OK
51     {
52         auto moveonly = MoveOnlyAwaitable();
53         co_await std::move(moveonly);
54     }
56     // GCC <= 11.2: OK
57     // GCC 11.3:ERROR:  error: use of deleted function 'MoveOnlyAwaitable::MoveOnlyAwaitable(const MoveOnlyAwaitable&)
58     // clang: OK
59     {
60         auto moveonly = MoveOnlyAwaitable();
61         co_await moveonly;
62     }