[libcxx-commits] [libcxx] 6441536 - [libcxx] [Coroutines] Support noop_coroutine for GCC
Chuanqi Xu via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Dec 26 21:54:28 PST 2021
Author: Chuanqi Xu
Date: 2021-12-27T13:53:21+08:00
New Revision: 6441536c27cfac46e4a6c5801dc01d5bdcf200c2
URL: https://github.com/llvm/llvm-project/commit/6441536c27cfac46e4a6c5801dc01d5bdcf200c2
DIFF: https://github.com/llvm/llvm-project/commit/6441536c27cfac46e4a6c5801dc01d5bdcf200c2.diff
LOG: [libcxx] [Coroutines] Support noop_coroutine for GCC
We didn't support noop_coroutine for GCC in previous conforming patch.
So that GCC couldn't use noop_coroutine() defined in <coroutine>. And
after this patch, GCC should be able to compile the whole <coroutine>
header.
Reviewed By: Quuxplusone
Differential Revision: https://reviews.llvm.org/D116144
Added:
Modified:
libcxx/docs/Status/Cxx2bIssues.csv
libcxx/include/__coroutine/noop_coroutine_handle.h
libcxx/test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index 902a18228c123..025a0c12d3317 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -37,7 +37,7 @@
"`3449 <https://wg21.link/LWG3449>`__","``take_view`` and ``take_while_view``'s ``sentinel<false>`` not comparable with their ``const iterator``","November 2020","","","|ranges|"
"`3453 <https://wg21.link/LWG3453>`__","Generic code cannot call ``ranges::advance(i, s)``","November 2020","","","|ranges|"
"`3455 <https://wg21.link/LWG3455>`__","Incorrect Postconditions on ``unique_ptr`` move assignment","November 2020","|Nothing To Do|",""
-"`3460 <https://wg21.link/LWG3460>`__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","",""
+"`3460 <https://wg21.link/LWG3460>`__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","|Complete|","14.0"
"`3461 <https://wg21.link/LWG3461>`__","``convertible_to``'s description mishandles cv-qualified ``void``","November 2020","",""
"`3465 <https://wg21.link/LWG3465>`__","``compare_partial_order_fallback`` requires ``F < E``","November 2020","","","|spaceship|"
"`3466 <https://wg21.link/LWG3466>`__","Specify the requirements for ``promise``/``future``/``shared_future`` consistently","November 2020","",""
diff --git a/libcxx/include/__coroutine/noop_coroutine_handle.h b/libcxx/include/__coroutine/noop_coroutine_handle.h
index 9dbf21aac5e6b..a29e202f4e4fd 100644
--- a/libcxx/include/__coroutine/noop_coroutine_handle.h
+++ b/libcxx/include/__coroutine/noop_coroutine_handle.h
@@ -20,7 +20,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__builtin_coro_noop)
+#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
+
// [coroutine.noop]
// [coroutine.promise.noop]
struct noop_coroutine_promise {};
@@ -64,20 +65,45 @@ struct _LIBCPP_TEMPLATE_VIS coroutine_handle<noop_coroutine_promise> {
_LIBCPP_HIDE_FROM_ABI
friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
+#if __has_builtin(__builtin_coro_noop)
_LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept {
this->__handle_ = __builtin_coro_noop();
}
void* __handle_ = nullptr;
+
+#elif defined(_LIBCPP_COMPILER_GCC)
+ // GCC doesn't implement __builtin_coro_noop().
+ // Construct the coroutine frame manually instead.
+ struct __noop_coroutine_frame_ty_ {
+ static void __dummy_resume_destroy_func() { }
+
+ void (*__resume_)() = __dummy_resume_destroy_func;
+ void (*__destroy_)() = __dummy_resume_destroy_func;
+ struct noop_coroutine_promise __promise_;
+ };
+
+ static __noop_coroutine_frame_ty_ __noop_coroutine_frame_;
+
+ void* __handle_ = &__noop_coroutine_frame_;
+
+ _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default;
+
+#endif // __has_builtin(__builtin_coro_noop)
};
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
+#if defined(_LIBCPP_COMPILER_GCC)
+inline noop_coroutine_handle::__noop_coroutine_frame_ty_
+ noop_coroutine_handle::__noop_coroutine_frame_{};
+#endif
+
// [coroutine.noop.coroutine]
inline _LIBCPP_HIDE_FROM_ABI
noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
-#endif // __has_builtin(__builtin_coro_noop)
+#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp b/libcxx/test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp
index 36a567983b280..215f44953c5a6 100644
--- a/libcxx/test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp
+++ b/libcxx/test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp
@@ -21,8 +21,6 @@
#include "test_macros.h"
-#if __has_builtin(__builtin_coro_noop)
-
static_assert(std::is_same<std::coroutine_handle<std::noop_coroutine_promise>, std::noop_coroutine_handle>::value, "");
static_assert(std::is_same<decltype(std::noop_coroutine()), std::noop_coroutine_handle>::value, "");
@@ -57,20 +55,25 @@ int main(int, char**)
h.resume();
h.destroy();
h();
- static_assert(h.done() == false, "");
static_assert(h, "");
+ static_assert(h.done() == false, "");
+
+ // [coroutine.handle.noop.resumption]p2
+ // Remarks: If noop_coroutine_handle is converted to
+ // coroutine_handle<>, calls to operator(), resume and
+ // destroy on that handle will also have no observable
+ // effects.
+ base.resume();
+ base.destroy();
+ base();
+ assert(base);
+ assert(base.done() == false);
h.promise();
assert(h.address() == base.address());
- assert(h==base);
+ assert(h == base);
assert(h.address() != nullptr);
assert(std::coroutine_handle<>::from_address(h.address()) == base);
return 0;
}
-
-#else
-
-int main(int, char**) { return 0; }
-
-#endif // __has_builtin(__builtin_coro_noop)
More information about the libcxx-commits
mailing list