[libcxx-commits] [libcxx] 9bde15d - [libc++] Deprecate std::launch::any extension (#173397)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 29 21:51:57 PST 2026
Author: sohail
Date: 2026-01-30T13:51:52+08:00
New Revision: 9bde15d76dd8d1c93ce7b9b2e25265f57ac3a9f4
URL: https://github.com/llvm/llvm-project/commit/9bde15d76dd8d1c93ce7b9b2e25265f57ac3a9f4
DIFF: https://github.com/llvm/llvm-project/commit/9bde15d76dd8d1c93ce7b9b2e25265f57ac3a9f4.diff
LOG: [libc++] Deprecate std::launch::any extension (#173397)
`std::launch::any` was a draft C++11 feature that was removed before the
final standard but it has remained in libc++ as an extension. This patch
marks it as deprecated and suggests using `std::launch::async |
std::launch::deferred` instead.
- Used `_LIBCPP_DEPRECATED_` to mark `std::launch::any` as deprecated
with an associated warning message recommending `std::launch::async |
std::launch::deferred` instead.
- Added a `.verify.cpp` test to validate the deprecation warning.
- Updated existing tests to avoid using the deprecated extension.
- Added note about deprecation in docs.
Fixes #173219
---------
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
libcxx/test/libcxx/thread/futures/launch_any_deprecated.verify.cpp
Modified:
libcxx/docs/ReleaseNotes/23.rst
libcxx/include/future
libcxx/test/libcxx/thread/nodiscard.verify.cpp
libcxx/test/std/thread/futures/futures.async/async.pass.cpp
libcxx/test/std/thread/futures/futures.overview/launch.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index bec665c167ce3..c19a731a006d7 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -46,6 +46,9 @@ Improvements and New Features
Deprecations and Removals
-------------------------
+- The ``std::launch::any`` enumerator that was accidentally provided as an extension is now deprecated.
+ It will be removed in LLVM 25.
+
Potentially breaking changes
----------------------------
diff --git a/libcxx/include/future b/libcxx/include/future
index 4cd5e8ab2aec8..4084148e52af6 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -435,7 +435,12 @@ 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 25.") = async | deferred};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
# ifndef _LIBCPP_CXX03_LANG
@@ -1876,7 +1881,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/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/libcxx/thread/nodiscard.verify.cpp b/libcxx/test/libcxx/thread/nodiscard.verify.cpp
index fe4c2b091c080..23a7554d3095a 100644
--- a/libcxx/test/libcxx/thread/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/thread/nodiscard.verify.cpp
@@ -111,7 +111,7 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::async([]() {});
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::async(std::launch::any, []() {});
+ std::async(std::launch::async | std::launch::deferred, []() {});
}
#endif
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 81232492c2545..28ca384a37b65 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