Issue 91123
Summary coroutine frame from lambda
Labels new issue
Assignees
Reporter kelbon
    I think there are should be a way to create coroutine frame from lambda. There are use cases:

* when we sure dont need allocation here, just create a handle and pass into function which accepts coroutine handles
* when coroutine handle may be invoked concurrently from different threads ('when_any' implementation), but its not possible in standard C++ to handle this (calling .resume concurrently will lead to UB). With lambdas calling .resume concurrently may be handled with simple mutex
* to create 'always done' coroutine, just like std::noop_coroutine, but .done always returns true
* to create special coroutines, such as generator, which is always empty (without allocatons). This may be used in std::generator move operator (there are no default constructor for std::generator, but move constructor is present, so to create "default" state for such generator we can use some global generator object, which .resume does nothing and .destroy does nothing too)

I have "implementation", but for obvious reasons it is not good: it contains undefined behavior. And i dont know is it intentional, but clang ignores all noinline and std::launder hacks and just optimizes out all code every time (with O1/O2/O3):
https://godbolt.org/z/EP1b8Eb9x

```cpp
template <typename F>
struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) coroutine_frame {
  void (*resume)(void*) = &do_resume<std::decay_t<coroutine_frame>>;
  void (*destroy)(void*) = &do_destroy<std::decay_t<coroutine_frame>>;
  F f;

 coroutine_frame(F value) : f(std::move(value)) {}

  [[gnu::noinline]] std::coroutine_handle<> handle() noexcept {
    return std::coroutine_handle<>::from_address(std::launder(this));
 }
};
```


_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to