[PATCH] D145639: [Coroutines] Fix premature conversion of return object

Ilya Biryukov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 16 02:41:04 PDT 2023


ilya-biryukov added a comment.

Reverting the RVO breaks some coroutine code we have. The short repro is  https://gcc.godbolt.org/z/1543qc8Ee (code at the end of the post, very similar to the deleted constructor in `warn-throw-out-noexcept-coro.cpp`):
The RVO seems to be mandated by the standard and D145641 <https://reviews.llvm.org/D145641> is in the works to fix this.

Could we revert this change and wait for D145641 <https://reviews.llvm.org/D145641> to land before reverting existing RVO behavior?
This would unblock our compiler releases (we live at head). This looks like the right trade-off given that previous behavior was in Clang for more than a year after D117087 <https://reviews.llvm.org/D117087> landed.

Reproducer <https://gcc.godbolt.org/z/1543qc8Ee> (works in Clang 15 and GCC, fails in trunk):

  #include <coroutine>
  
  struct MyTask{
    struct promise_type {
      MyTask get_return_object() { return MyTask{std::coroutine_handle<promise_type>::from_promise(*this)}; }
      std::suspend_always initial_suspend() { return {}; }
  
      void unhandled_exception();
      void return_void() {} 
  
      auto await_transform(MyTask task) {
        struct Awaiter {
          bool await_ready() { return false; }
          std::coroutine_handle<promise_type> await_suspend(std::coroutine_handle<promise_type> h);
          std::nullptr_t await_resume();
  
          promise_type& caller;
          promise_type& callee;
        };
  
        return Awaiter{*this, task.handle.promise()};
      }
      
      auto final_suspend() noexcept {
        struct Awaiter {
          bool await_ready() noexcept { return false; }
          std::coroutine_handle<promise_type> await_suspend(std::coroutine_handle<promise_type> h) noexcept;
          void await_resume() noexcept;
  
          std::coroutine_handle<promise_type> to_resume;
        };
  
        return Awaiter{resume_when_done};
      }
  
      // The coroutine to resume when we're done.
      std::coroutine_handle<promise_type> resume_when_done;
    };
  
    explicit MyTask(std::coroutine_handle<promise_type>);
    MyTask(MyTask&&) = delete;
  
    // A handle for the coroutine that returned this task.
    std::coroutine_handle<promise_type> handle;
  };
  
  MyTask DoNothing() {
    co_return;
  }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145639/new/

https://reviews.llvm.org/D145639



More information about the cfe-commits mailing list