[libcxx-commits] [libcxx] [libc++] Deprecate std::launch::any extension (PR #173397)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 24 04:41:49 PST 2025


https://github.com/sohail103 updated https://github.com/llvm/llvm-project/pull/173397

>From b7ea55525fb627f516e572db127c2eb3c7234ca4 Mon Sep 17 00:00:00 2001
From: sohail103 <sohailraj.satapathy at gmail.com>
Date: Tue, 23 Dec 2025 17:07:21 +0000
Subject: [PATCH] [libc++] Deprecate non-standard std::launch::any extension

std::launch::any was a draft C++11 feature that was removed before the final standard.
It has remained in libc++ as an extension. This patch marks it as deprecated to warn users
who might be relying on it unintentionally.

- Replaced internal usage of std::launch::any in std::async with standard flags.
- Added a verify test to check for the deprecation warning.
- Updated existing tests to expect the deprecation warning.

Fixes #173219
---
 libcxx/docs/ReleaseNotes/22.rst               |  2 ++
 libcxx/include/future                         | 10 +++++--
 .../diagnostics/future.nodiscard.verify.cpp   |  2 +-
 .../futures/launch_any_deprecated.verify.cpp  | 22 +++++++++++++++
 .../futures/futures.async/async.pass.cpp      |  1 -
 .../futures/futures.overview/launch.pass.cpp  | 28 ++++++++-----------
 6 files changed, 44 insertions(+), 21 deletions(-)
 create mode 100644 libcxx/test/libcxx/thread/futures/launch_any_deprecated.verify.cpp

diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 82271be7a22ab..502fa3d15bc6b 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -102,6 +102,8 @@ Improvements and New Features
 Deprecations and Removals
 -------------------------
 
+- Extension ``launch::any`` is deprecated. It will be removed in LLVM 24.
+
 Potentially breaking changes
 ----------------------------
 
diff --git a/libcxx/include/future b/libcxx/include/future
index c249bc5e7938f..3f578ed4936dd 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -434,7 +434,13 @@ struct is_error_code_enum<future_errc::__lx> : public true_type {};
 #    endif
 
 // enum class launch
-_LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred};
+_LIBCPP_DECLARE_STRONG_ENUM(launch){
+  async = 1, 
+  deferred = 2, 
+  any _LIBCPP_DEPRECATED_("std::launch::any is a deprecated extension. "
+                             "Use std::launch::async | std::launch::deferred instead. "
+                             "It will be removed in LLVM 24.") = async | deferred
+};
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
 
 #    ifndef _LIBCPP_CXX03_LANG
@@ -1872,7 +1878,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args) {
 template <class _Fp, class... _Args>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI future<__invoke_result_t<__decay_t<_Fp>, __decay_t<_Args>...> >
 async(_Fp&& __f, _Args&&... __args) {
-  return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
+  return std::async(launch::async | launch::deferred, std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
 }
 
 #    endif // C++03
diff --git a/libcxx/test/libcxx/diagnostics/future.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/future.nodiscard.verify.cpp
index cc5c6135d109b..4ba2e69b3df28 100644
--- a/libcxx/test/libcxx/diagnostics/future.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/future.nodiscard.verify.cpp
@@ -18,5 +18,5 @@
 
 void test() {
   std::async([]() {});                   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::async(std::launch::any, []() {}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::async(std::launch::async | std::launch::deferred, []() {}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 }
diff --git a/libcxx/test/libcxx/thread/futures/launch_any_deprecated.verify.cpp b/libcxx/test/libcxx/thread/futures/launch_any_deprecated.verify.cpp
new file mode 100644
index 0000000000000..28e02b2c646f0
--- /dev/null
+++ b/libcxx/test/libcxx/thread/futures/launch_any_deprecated.verify.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+
+// <future>
+
+// enum class launch;
+
+// Verify that std::launch::any is deprecated.
+// It was a draft C++11 feature that was removed, but libc++ kept it as an extension.
+
+#include <future>
+
+void test() {
+  (void)std::launch::any; // expected-warning {{std::launch::any is a deprecated extension}}
+}
diff --git a/libcxx/test/std/thread/futures/futures.async/async.pass.cpp b/libcxx/test/std/thread/futures/futures.async/async.pass.cpp
index 109372b50a311..aaec289f0a0ce 100644
--- a/libcxx/test/std/thread/futures/futures.async/async.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.async/async.pass.cpp
@@ -114,7 +114,6 @@ int main(int, char**)
     bool DPID = DefaultPolicyIsDeferred;
 
     std::launch AnyPolicy = std::launch::async | std::launch::deferred;
-    LIBCPP_ASSERT(AnyPolicy == std::launch::any);
 
     {
         auto checkInt = [](std::future<int>& f) { return f.get() == 3; };
diff --git a/libcxx/test/std/thread/futures/futures.overview/launch.pass.cpp b/libcxx/test/std/thread/futures/futures.overview/launch.pass.cpp
index 37ad2ff4a8645..a894a8600676d 100644
--- a/libcxx/test/std/thread/futures/futures.overview/launch.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.overview/launch.pass.cpp
@@ -14,7 +14,6 @@
 // {
 //     async = 1,
 //     deferred = 2,
-//     any = async | deferred /* EXTENSION */
 // };
 
 #include <future>
@@ -24,22 +23,17 @@
 
 int main(int, char**)
 {
-#if TEST_STD_VER < 11
-   LIBCPP_STATIC_ASSERT(static_cast<int>(std::launch::any) ==
-                 (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), "");
-#else
-    LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async | std::launch::deferred), "");
-    static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), "");
-    LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async ^ std::launch::deferred), "");
-    LIBCPP_STATIC_ASSERT(std::launch::deferred == ~std::launch::async, "");
-    std::launch x = std::launch::async;
-    x &= std::launch::deferred;
-    assert(x == std::launch(0));
-    x = std::launch::async;
-    x |= std::launch::deferred;
-    LIBCPP_ASSERT(x == std::launch::any);
-    x ^= std::launch::deferred;
-    assert(x == std::launch::async);
+#if TEST_STD_VER >= 11
+  static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), "");
+  LIBCPP_STATIC_ASSERT(std::launch::deferred == ~std::launch::async, "");
+  std::launch x = std::launch::async;
+  x &= std::launch::deferred;
+  assert(x == std::launch(0));
+  x = std::launch::async;
+  x |= std::launch::deferred;
+  assert(x == (std::launch::async | std::launch::deferred));
+  x ^= std::launch::deferred;
+  assert(x == std::launch::async);
 #endif
     static_assert(static_cast<int>(std::launch::async) == 1, "");
     static_assert(static_cast<int>(std::launch::deferred) == 2, "");



More information about the libcxx-commits mailing list