diff --git a/include/experimental/coroutine b/include/experimental/coroutine index 21c1ea566..ce795ad45 100644 --- a/include/experimental/coroutine +++ b/include/experimental/coroutine @@ -250,9 +250,11 @@ public: _LIBCPP_ALWAYS_INLINE static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT { + typedef typename remove_cv<_Promise>::type _RawPromise; coroutine_handle __tmp; - __tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise), - __alignof(_Promise), true); + __tmp.__handle_ = __builtin_coro_promise( + _VSTD::addressof(const_cast<_RawPromise&>(__promise)), + __alignof(_Promise), true); return __tmp; } }; diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp index 4a61047a8..f996886c4 100644 --- a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp +++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp @@ -28,6 +28,39 @@ namespace coro = std::experimental; +struct MyCoro { + struct promise_type { + void unhandled_exception() {} + void return_void() {} + coro::suspend_never initial_suspend() { return {}; } + coro::suspend_never final_suspend() { return {}; } + MyCoro get_return_object() { + do_runtime_test(); + return {}; + } + void do_runtime_test() { + // Test that a coroutine_handle can be created from a const + // promise_type and that it represents the same coroutine as + // coroutine_handle + using CH = coro::coroutine_handle; + using CCH = coro::coroutine_handle; + const auto &cthis = *this; + CH h = CH::from_promise(*this); + CCH h2 = CCH::from_promise(*this); + CCH h3 = CCH::from_promise(cthis); + assert(&h.promise() == this); + assert(&h2.promise() == this); + assert(&h3.promise() == this); + assert(h.address() == h2.address()); + assert(h2.address() == h3.address()); + } + }; +}; + +MyCoro do_runtime_test() { + co_await coro::suspend_never{}; +} + template void do_test(coro::coroutine_handle&& H) { @@ -46,4 +79,6 @@ void do_test(coro::coroutine_handle&& H) { int main() { do_test(coro::coroutine_handle{}); + do_test(coro::coroutine_handle{}); + do_runtime_test(); }