[libcxx-commits] [libcxx] [libc++] Prevent std::terminate in promise<void> destructor race (PR #221258)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 4 08:37:22 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Eamon  (Eamon2009)

<details>
<summary>Changes</summary>

promise<void>::~promise() calls set_exception() to inject a broken_promise when the promise is destroyed before the shared state is ready. That call can throw (e.g. promise_already_satisfied if a race occurs, or bad_alloc from make_exception_ptr). Because destructors are implicitly noexcept, an escaping exception triggers std::terminate.

Wrap the set_exception call in a try/catch block so the destructor is truly noexcept.

---
Full diff: https://github.com/llvm/llvm-project/pull/221258.diff


1 Files Affected:

- (modified) libcxx/src/future.cpp (+6-2) 


``````````diff
diff --git a/libcxx/src/future.cpp b/libcxx/src/future.cpp
index 284b68828c7fd..a0e59732b4cd1 100644
--- a/libcxx/src/future.cpp
+++ b/libcxx/src/future.cpp
@@ -144,8 +144,12 @@ promise<void>::promise() : __state_(new __assoc_sub_state) {}
 promise<void>::~promise() {
   if (__state_) {
 #if _LIBCPP_HAS_EXCEPTIONS
-    if (!__state_->__has_value() && __state_->use_count() > 1)
-      __state_->set_exception(make_exception_ptr(future_error(future_errc::broken_promise)));
+    if (!__state_->__has_value() && __state_->use_count() > 1) {
+      try {
+        __state_->set_exception(make_exception_ptr(future_error(future_errc::broken_promise)));
+      } catch (...) {
+      }
+    }
 #endif // _LIBCPP_HAS_EXCEPTIONS
     __state_->__release_shared();
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/221258


More information about the libcxx-commits mailing list