[libcxx-commits] [libcxx] [libc++] Throw future_error in future.get() (PR #179409)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Apr 23 03:33:08 PDT 2026


https://github.com/Ekkorus101 updated https://github.com/llvm/llvm-project/pull/179409

>From d61d198c3189cf93267d73bb7e136752b2612310 Mon Sep 17 00:00:00 2001
From: zhangqingchun <zhangqingchun at bytedance.com>
Date: Thu, 23 Apr 2026 16:15:26 +0800
Subject: [PATCH] add future error for std::future::get()

---
 libcxx/include/future                         |  4 ++
 libcxx/src/future.cpp                         |  2 +
 .../futures.unique_future/get.pass.cpp        | 69 +++++++++++++++++++
 3 files changed, 75 insertions(+)

diff --git a/libcxx/include/future b/libcxx/include/future
index 6bd836afa04e8..3874d1036857f 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -985,6 +985,8 @@ future<_Rp>::~future() {
 
 template <class _Rp>
 _Rp future<_Rp>::get() {
+  if (__state_ == nullptr)
+    std::__throw_future_error(future_errc::no_state);
   unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
   __assoc_state<_Rp>* __s = __state_;
   __state_                = nullptr;
@@ -1052,6 +1054,8 @@ future<_Rp&>::~future() {
 
 template <class _Rp>
 _Rp& future<_Rp&>::get() {
+  if (__state_ == nullptr)
+    std::__throw_future_error(future_errc::no_state);
   unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
   __assoc_state<_Rp&>* __s = __state_;
   __state_                 = nullptr;
diff --git a/libcxx/src/future.cpp b/libcxx/src/future.cpp
index 7bba635e9006f..ad9ec2ef01a3d 100644
--- a/libcxx/src/future.cpp
+++ b/libcxx/src/future.cpp
@@ -132,6 +132,8 @@ future<void>::~future() {
 }
 
 void future<void>::get() {
+  if (__state_ == nullptr)
+    std::__throw_future_error(future_errc::no_state);
   unique_ptr<__shared_count, __release_shared_count> __(__state_);
   __assoc_sub_state* __s = __state_;
   __state_               = nullptr;
diff --git a/libcxx/test/std/thread/futures/futures.unique_future/get.pass.cpp b/libcxx/test/std/thread/futures/futures.unique_future/get.pass.cpp
index 65f3d2199ccdd..0a20eb9dbff97 100644
--- a/libcxx/test/std/thread/futures/futures.unique_future/get.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.unique_future/get.pass.cpp
@@ -152,5 +152,74 @@ int main(int, char**)
 #endif
     }
 
+
+#if defined(_LIBCPP_VERSION) && !defined(TEST_HAS_NO_EXCEPTIONS)
+    {
+        std::future<int> f;
+        try {
+            (void)f.get();
+            assert(false);
+        } catch (const std::future_error& e) {
+            assert(e.code() == std::make_error_code(std::future_errc::no_state));
+        }
+    }
+    {
+        std::promise<int> p;
+        std::future<int> f = p.get_future();
+        p.set_value(3);
+        (void)f.get();
+        try {
+            (void)f.get();
+            assert(false);
+        } catch (const std::future_error& e) {
+            assert(e.code() == std::make_error_code(std::future_errc::no_state));
+        }
+    }
+    {
+        std::future<int&> f;
+        try {
+            (void)f.get();
+            assert(false);
+        } catch (const std::future_error& e) {
+            assert(e.code() == std::make_error_code(std::future_errc::no_state));
+        }
+    }
+    {
+        std::promise<int&> p;
+        std::future<int&> f = p.get_future();
+        int j_val = 5;
+        p.set_value(j_val);
+        (void)f.get();
+        try {
+            (void)f.get();
+            assert(false);
+        } catch (const std::future_error& e) {
+            assert(e.code() == std::make_error_code(std::future_errc::no_state));
+        }
+    }
+    {
+        std::future<void> f;
+        try {
+            (void)f.get();
+            assert(false);
+        } catch (const std::future_error& e) {
+            assert(e.code() == std::make_error_code(std::future_errc::no_state));
+        }
+    }
+    {
+        std::promise<void> p;
+        std::future<void> f = p.get_future();
+        p.set_value();
+        (void)f.get();
+        try {
+            (void)f.get();
+            assert(false);
+        } catch (const std::future_error& e) {
+            assert(e.code() == std::make_error_code(std::future_errc::no_state));
+        }
+    }
+#endif
+
   return 0;
 }
+



More information about the libcxx-commits mailing list