[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