[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:36:31 PDT 2026


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

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.

>From ec8c1e7e48491b91d67c8f15fd52c00f2a9a997b Mon Sep 17 00:00:00 2001
From: Eamon <eamon112009 at gmail.com>
Date: Fri, 4 Sep 2026 21:06:08 +0530
Subject: [PATCH] [libc++] Prevent std::terminate in promise<void> destructor
 race

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.
---
 libcxx/src/future.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

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();
   }



More information about the libcxx-commits mailing list