[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