[libcxx-commits] [libcxx] [libc++] Assume that <atomic> is available (PR #199674)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 26 08:15:30 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/199674

>From 5b8acdb9adad148de8adb448dd8f12fb07632de5 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 21 May 2026 11:45:44 +0200
Subject: [PATCH 1/2] [libc++] Remove ios_base::__xindex_ from the ABI

---
 libcxx/include/ios                            | 16 ++++-------
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...bcxxabi.v1.stable.exceptions.nonew.abilist |  1 -
 ...xxabi.v1.stable.noexceptions.nonew.abilist |  1 -
 libcxx/src/ios.cpp                            | 13 ++++-----
 .../test/libcxx/transitive_includes/cxx26.csv | 28 -------------------
 12 files changed, 10 insertions(+), 56 deletions(-)

diff --git a/libcxx/include/ios b/libcxx/include/ios
index d1ec14cba37d1..945fd68643a7a 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -235,10 +235,6 @@ storage-class-specifier const error_category& iostream_category() noexcept;
 #    include <__verbose_abort>
 #    include <version>
 
-#    if _LIBCPP_HAS_ATOMIC_HEADER
-#      include <__atomic/atomic.h> // for __xindex_
-#    endif
-
 #    if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #      pragma GCC system_header
 #    endif
@@ -406,13 +402,6 @@ private:
   int* __index_;
   size_t __event_size_;
   size_t __event_cap_;
-// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only
-// enabled with clang.
-#    if _LIBCPP_HAS_C_ATOMIC_IMP && _LIBCPP_HAS_THREADS
-  static atomic<int> __xindex_;
-#    else
-  static int __xindex_;
-#    endif
   long* __iarray_;
   size_t __iarray_size_;
   size_t __iarray_cap_;
@@ -886,6 +875,11 @@ _LIBCPP_POP_MACROS
 
 #  endif // _LIBCPP_HAS_LOCALIZATION
 
+#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
+#    include <ctime>
+#    include <ratio>
+#  endif
+
 #  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #    include <atomic>
 #    include <concepts>
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index da1e340b1d4aa..d1fd0cef6b774 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1869,7 +1869,6 @@
 {'is_defined': True, 'name': '__ZNSt3__18ios_base7unitbufE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base8internalE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base8showbaseE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZNSt3__18ios_base9__xindex_E', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base9basefieldE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base9boolalphaE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base9showpointE', 'size': 0, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
index 814fa26349b3d..b0cd73f9a6bfe 100644
--- a/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1507,7 +1507,6 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base7unitbufE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base8internalE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base8showbaseE', 'size': 4, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9__xindex_E', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9basefieldE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9boolalphaE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9showpointE', 'size': 4, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index c4b8a79985be5..85c5839dd7c8e 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -826,7 +826,6 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base7unitbufE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base8internalE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base8showbaseE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9__xindex_E', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9basefieldE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9boolalphaE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9showpointE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 8daf957e6e55f..a4dfab8897962 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -826,7 +826,6 @@
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base7unitbufE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base8internalE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base8showbaseE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9__xindex_E', 'storage_mapping_class': 'RW', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9basefieldE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9boolalphaE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
 {'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__18ios_base9showpointE', 'storage_mapping_class': 'RO', 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 281f2f374b78f..d14fa14a19bbd 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1859,7 +1859,6 @@
 {'is_defined': True, 'name': '__ZNSt3__18ios_base7unitbufE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base8internalE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base8showbaseE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZNSt3__18ios_base9__xindex_E', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base9basefieldE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base9boolalphaE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__18ios_base9showpointE', 'size': 0, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
index 975d7ae118bf5..b2ca72e70b08d 100644
--- a/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android23.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1507,7 +1507,6 @@
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base7unitbufE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base8internalE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base8showbaseE', 'size': 4, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9__xindex_E', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9basefieldE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9boolalphaE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt6__ndk18ios_base9showpointE', 'size': 4, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index b27dab3d9203e..85fcda288daa2 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1519,7 +1519,6 @@
 {'is_defined': True, 'name': '_ZNSt3__18ios_base7unitbufE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base8internalE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base8showbaseE', 'size': 4, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZNSt3__18ios_base9__xindex_E', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9basefieldE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9boolalphaE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9showpointE', 'size': 4, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index e5372de54c40e..669930a06a6db 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1518,7 +1518,6 @@
 {'is_defined': True, 'name': '_ZNSt3__18ios_base7unitbufE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base8internalE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base8showbaseE', 'size': 4, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZNSt3__18ios_base9__xindex_E', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9basefieldE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9boolalphaE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9showpointE', 'size': 4, 'type': 'OBJECT'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 4def06bc737ce..2e897e689db5b 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -1489,7 +1489,6 @@
 {'is_defined': True, 'name': '_ZNSt3__18ios_base7unitbufE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base8internalE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base8showbaseE', 'size': 4, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZNSt3__18ios_base9__xindex_E', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9basefieldE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9boolalphaE', 'size': 4, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__18ios_base9showpointE', 'size': 4, 'type': 'OBJECT'}
diff --git a/libcxx/src/ios.cpp b/libcxx/src/ios.cpp
index 3a8147a0f9d13..2e049098740dc 100644
--- a/libcxx/src/ios.cpp
+++ b/libcxx/src/ios.cpp
@@ -9,6 +9,7 @@
 #include <__config>
 #include <__locale>
 #include <algorithm>
+#include <atomic>
 #include <ios>
 #include <limits>
 #include <memory>
@@ -111,13 +112,6 @@ locale ios_base::imbue(const locale& newloc) {
 
 locale ios_base::getloc() const { return __loc_; }
 
-// xalloc
-#if _LIBCPP_HAS_C_ATOMIC_IMP && _LIBCPP_HAS_THREADS
-atomic<int> ios_base::__xindex_{0};
-#else
-int ios_base::__xindex_ = 0;
-#endif
-
 template <typename _Tp>
 static size_t __ios_new_cap(size_t __req_size, size_t __current_cap) { // Precondition: __req_size > __current_cap
   const size_t mx = std::numeric_limits<size_t>::max() / sizeof(_Tp);
@@ -127,7 +121,10 @@ static size_t __ios_new_cap(size_t __req_size, size_t __current_cap) { // Precon
     return mx;
 }
 
-int ios_base::xalloc() { return __xindex_++; }
+int ios_base::xalloc() {
+  constinit static atomic<int> xindex = 0;
+  return xindex++;
+}
 
 long& ios_base::iword(int index) {
   size_t req_size = static_cast<size_t>(index) + 1;
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 253cf64703076..f075a9c741105 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -72,7 +72,6 @@ ccomplex cstdint
 ccomplex cstdio
 ccomplex cstdlib
 ccomplex cstring
-ccomplex ctime
 ccomplex cwchar
 ccomplex cwctype
 ccomplex initializer_list
@@ -80,7 +79,6 @@ ccomplex ios
 ccomplex iosfwd
 ccomplex istream
 ccomplex limits
-ccomplex ratio
 ccomplex sstream
 ccomplex stdexcept
 ccomplex streambuf
@@ -165,7 +163,6 @@ complex cstdint
 complex cstdio
 complex cstdlib
 complex cstring
-complex ctime
 complex cwchar
 complex cwctype
 complex initializer_list
@@ -173,7 +170,6 @@ complex ios
 complex iosfwd
 complex istream
 complex limits
-complex ratio
 complex sstream
 complex stdexcept
 complex streambuf
@@ -213,7 +209,6 @@ ctgmath cstdint
 ctgmath cstdio
 ctgmath cstdlib
 ctgmath cstring
-ctgmath ctime
 ctgmath cwchar
 ctgmath cwctype
 ctgmath initializer_list
@@ -221,7 +216,6 @@ ctgmath ios
 ctgmath iosfwd
 ctgmath istream
 ctgmath limits
-ctgmath ratio
 ctgmath sstream
 ctgmath stdexcept
 ctgmath streambuf
@@ -263,7 +257,6 @@ experimental/iterator cstdint
 experimental/iterator cstdio
 experimental/iterator cstdlib
 experimental/iterator cstring
-experimental/iterator ctime
 experimental/iterator cwchar
 experimental/iterator cwctype
 experimental/iterator initializer_list
@@ -271,7 +264,6 @@ experimental/iterator ios
 experimental/iterator iosfwd
 experimental/iterator iterator
 experimental/iterator limits
-experimental/iterator ratio
 experimental/iterator stdexcept
 experimental/iterator streambuf
 experimental/iterator string
@@ -392,7 +384,6 @@ fstream cstdint
 fstream cstdio
 fstream cstdlib
 fstream cstring
-fstream ctime
 fstream cwchar
 fstream cwctype
 fstream initializer_list
@@ -401,7 +392,6 @@ fstream ios
 fstream iosfwd
 fstream istream
 fstream limits
-fstream ratio
 fstream stdexcept
 fstream streambuf
 fstream string
@@ -463,14 +453,12 @@ iomanip cstdint
 iomanip cstdio
 iomanip cstdlib
 iomanip cstring
-iomanip ctime
 iomanip cwchar
 iomanip cwctype
 iomanip initializer_list
 iomanip ios
 iomanip iosfwd
 iomanip limits
-iomanip ratio
 iomanip stdexcept
 iomanip string
 iomanip string_view
@@ -487,13 +475,11 @@ ios cstdint
 ios cstdio
 ios cstdlib
 ios cstring
-ios ctime
 ios cwchar
 ios cwctype
 ios initializer_list
 ios iosfwd
 ios limits
-ios ratio
 ios stdexcept
 ios string
 ios string_view
@@ -513,7 +499,6 @@ iostream cstdint
 iostream cstdio
 iostream cstdlib
 iostream cstring
-iostream ctime
 iostream cwchar
 iostream cwctype
 iostream format
@@ -525,7 +510,6 @@ iostream limits
 iostream optional
 iostream ostream
 iostream print
-iostream ratio
 iostream stdexcept
 iostream streambuf
 iostream string
@@ -544,14 +528,12 @@ istream cstdint
 istream cstdio
 istream cstdlib
 istream cstring
-istream ctime
 istream cwchar
 istream cwctype
 istream initializer_list
 istream ios
 istream iosfwd
 istream limits
-istream ratio
 istream stdexcept
 istream streambuf
 istream string
@@ -600,14 +582,12 @@ locale cstdint
 locale cstdio
 locale cstdlib
 locale cstring
-locale ctime
 locale cwchar
 locale cwctype
 locale initializer_list
 locale ios
 locale iosfwd
 locale limits
-locale ratio
 locale stdexcept
 locale streambuf
 locale string
@@ -698,7 +678,6 @@ ostream cstdint
 ostream cstdio
 ostream cstdlib
 ostream cstring
-ostream ctime
 ostream cwchar
 ostream cwctype
 ostream format
@@ -708,7 +687,6 @@ ostream iosfwd
 ostream limits
 ostream optional
 ostream print
-ostream ratio
 ostream stdexcept
 ostream streambuf
 ostream string
@@ -871,7 +849,6 @@ sstream cstdint
 sstream cstdio
 sstream cstdlib
 sstream cstring
-sstream ctime
 sstream cwchar
 sstream cwctype
 sstream initializer_list
@@ -879,7 +856,6 @@ sstream ios
 sstream iosfwd
 sstream istream
 sstream limits
-sstream ratio
 sstream stdexcept
 sstream streambuf
 sstream string
@@ -917,14 +893,12 @@ streambuf cstdint
 streambuf cstdio
 streambuf cstdlib
 streambuf cstring
-streambuf ctime
 streambuf cwchar
 streambuf cwctype
 streambuf initializer_list
 streambuf ios
 streambuf iosfwd
 streambuf limits
-streambuf ratio
 streambuf stdexcept
 streambuf string
 streambuf string_view
@@ -969,7 +943,6 @@ strstream cstdint
 strstream cstdio
 strstream cstdlib
 strstream cstring
-strstream ctime
 strstream cwchar
 strstream cwctype
 strstream initializer_list
@@ -977,7 +950,6 @@ strstream ios
 strstream iosfwd
 strstream istream
 strstream limits
-strstream ratio
 strstream stdexcept
 strstream streambuf
 strstream string

>From 56e62eb555ab7a122c2a7bd5879a0eb380aac034 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 26 May 2026 15:18:34 +0200
Subject: [PATCH 2/2] [libc++] Assume that <atomic> is available

---
 libcxx/include/__atomic/atomic_flag.h     |  5 ++++
 libcxx/include/__atomic/support.h         |  4 +--
 libcxx/include/__config                   | 19 ------------
 libcxx/include/__memory/shared_ptr.h      |  4 +--
 libcxx/include/atomic                     |  4 ---
 libcxx/modules/std.cppm.in                |  4 +--
 libcxx/src/memory_resource.cpp            | 35 +----------------------
 libcxx/utils/generate_libcxx_cppm_in.py   | 12 +-------
 libcxx/utils/libcxx/header_information.py |  6 ----
 libcxx/utils/libcxx/test/modules.py       | 11 +------
 10 files changed, 12 insertions(+), 92 deletions(-)

diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h
index 7c09870867b70..483562f969881 100644
--- a/libcxx/include/__atomic/atomic_flag.h
+++ b/libcxx/include/__atomic/atomic_flag.h
@@ -22,6 +22,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+// FIXME: Do we actually want to allow users to change the flag type used?
+#ifndef _LIBCPP_ATOMIC_FLAG_TYPE
+#  define _LIBCPP_ATOMIC_FLAG_TYPE bool
+#endif
+
 struct atomic_flag {
   __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
 
diff --git a/libcxx/include/__atomic/support.h b/libcxx/include/__atomic/support.h
index 99d0f6aa543ca..053ad54aa6ce5 100644
--- a/libcxx/include/__atomic/support.h
+++ b/libcxx/include/__atomic/support.h
@@ -102,9 +102,9 @@
 // clang-format on
 //
 
-#if _LIBCPP_HAS_GCC_ATOMIC_IMP
+#ifdef _LIBCPP_COMPILER_GCC
 #  include <__atomic/support/gcc.h>
-#elif _LIBCPP_HAS_C_ATOMIC_IMP
+#else
 #  include <__atomic/support/c11.h>
 #endif
 
diff --git a/libcxx/include/__config b/libcxx/include/__config
index a34c6ee502bb2..c7ca864e8d27c 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -381,25 +381,6 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
 #  endif
 
-#  if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic)
-#    define _LIBCPP_HAS_C_ATOMIC_IMP 1
-#    define _LIBCPP_HAS_GCC_ATOMIC_IMP 0
-#    define _LIBCPP_HAS_EXTERNAL_ATOMIC_IMP 0
-#  elif defined(_LIBCPP_COMPILER_GCC)
-#    define _LIBCPP_HAS_C_ATOMIC_IMP 0
-#    define _LIBCPP_HAS_GCC_ATOMIC_IMP 1
-#    define _LIBCPP_HAS_EXTERNAL_ATOMIC_IMP 0
-#  endif
-
-#  if !_LIBCPP_HAS_C_ATOMIC_IMP && !_LIBCPP_HAS_GCC_ATOMIC_IMP && !_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP
-#    define _LIBCPP_HAS_ATOMIC_HEADER 0
-#  else
-#    define _LIBCPP_HAS_ATOMIC_HEADER 1
-#    ifndef _LIBCPP_ATOMIC_FLAG_TYPE
-#      define _LIBCPP_ATOMIC_FLAG_TYPE bool
-#    endif
-#  endif
-
 // We often repeat things just for handling wide characters in the library.
 // When wide characters are disabled, it can be useful to have a quick way of
 // disabling it without having to resort to #if-#endif, which has a larger
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index e621e89027d20..ec3882ab34074 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -10,6 +10,7 @@
 #ifndef _LIBCPP___MEMORY_SHARED_PTR_H
 #define _LIBCPP___MEMORY_SHARED_PTR_H
 
+#include <__atomic/memory_order.h>
 #include <__compare/compare_three_way.h>
 #include <__compare/ordering.h>
 #include <__config>
@@ -58,9 +59,6 @@
 #include <__utility/swap.h>
 #include <__verbose_abort>
 #include <typeinfo>
-#if _LIBCPP_HAS_ATOMIC_HEADER
-#  include <__atomic/memory_order.h>
-#endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index 23a3db5d35029..d1d59d949a394 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -626,10 +626,6 @@ template <class T>
 #    pragma GCC system_header
 #  endif
 
-#  if !_LIBCPP_HAS_ATOMIC_HEADER
-#    error <atomic> is not implemented
-#  endif
-
 #  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #    include <cmath>
 #    include <compare>
diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in
index 984b18321923c..6de6369c3387f 100644
--- a/libcxx/modules/std.cppm.in
+++ b/libcxx/modules/std.cppm.in
@@ -20,9 +20,7 @@ module;
 #include <algorithm>
 #include <any>
 #include <array>
-#if _LIBCPP_HAS_ATOMIC_HEADER
-#  include <atomic>
-#endif
+#include <atomic>
 #include <barrier>
 #include <bit>
 #include <bitset>
diff --git a/libcxx/src/memory_resource.cpp b/libcxx/src/memory_resource.cpp
index 00307e107faa6..c58e4a3790b25 100644
--- a/libcxx/src/memory_resource.cpp
+++ b/libcxx/src/memory_resource.cpp
@@ -6,19 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <atomic>
 #include <cstddef>
 #include <memory>
 #include <memory_resource>
 
-#if _LIBCPP_HAS_ATOMIC_HEADER
-#  include <atomic>
-#elif _LIBCPP_HAS_THREADS
-#  include <mutex>
-#  if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
-#    pragma comment(lib, "pthread")
-#  endif
-#endif
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
@@ -95,7 +87,6 @@ memory_resource* null_memory_resource() noexcept { return &res_init.resources.nu
 // default_memory_resource()
 
 static memory_resource* __default_memory_resource(bool set = false, memory_resource* new_res = nullptr) noexcept {
-#if _LIBCPP_HAS_ATOMIC_HEADER
   static constinit atomic<memory_resource*> __res{&res_init.resources.new_delete_res};
   if (set) {
     new_res = new_res ? new_res : new_delete_resource();
@@ -104,30 +95,6 @@ static memory_resource* __default_memory_resource(bool set = false, memory_resou
   } else {
     return std::atomic_load_explicit(&__res, memory_order_acquire);
   }
-#elif _LIBCPP_HAS_THREADS
-  static constinit memory_resource* res = &res_init.resources.new_delete_res;
-  static mutex res_lock;
-  if (set) {
-    new_res = new_res ? new_res : new_delete_resource();
-    lock_guard<mutex> guard(res_lock);
-    memory_resource* old_res = res;
-    res                      = new_res;
-    return old_res;
-  } else {
-    lock_guard<mutex> guard(res_lock);
-    return res;
-  }
-#else
-  static constinit memory_resource* res = &res_init.resources.new_delete_res;
-  if (set) {
-    new_res                  = new_res ? new_res : new_delete_resource();
-    memory_resource* old_res = res;
-    res                      = new_res;
-    return old_res;
-  } else {
-    return res;
-  }
-#endif
 }
 
 memory_resource* get_default_resource() noexcept { return __default_memory_resource(); }
diff --git a/libcxx/utils/generate_libcxx_cppm_in.py b/libcxx/utils/generate_libcxx_cppm_in.py
index 26d680a0db31f..fac33f74812a7 100644
--- a/libcxx/utils/generate_libcxx_cppm_in.py
+++ b/libcxx/utils/generate_libcxx_cppm_in.py
@@ -12,7 +12,6 @@
 from libcxx.header_information import (
     module_c_headers,
     module_headers,
-    header_restrictions,
     headers_not_available,
     libcxx_root,
 )
@@ -46,16 +45,7 @@ def write_file(module):
 """
         )
         for header in sorted(module_headers if module == "std" else module_c_headers):
-            if header in header_restrictions:
-                module_cpp_in.write(
-                    f"""\
-#if {header_restrictions[header]}
-#  include <{header}>
-#endif
-"""
-                )
-            else:
-                module_cpp_in.write(f"#include <{header}>\n")
+            module_cpp_in.write(f"#include <{header}>\n")
 
         module_cpp_in.write(
             """
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index d06271a7908cc..384ff9f759460 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -175,12 +175,6 @@ def __hash__(self) -> int:
     "text_encoding",
 ]))
 
-header_restrictions = {
-    # headers with #error directives
-    "atomic": "_LIBCPP_HAS_ATOMIC_HEADER",
-    "stdatomic.h": "_LIBCPP_HAS_ATOMIC_HEADER",
-}
-
 lit_header_restrictions = {
     "barrier": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
     "coroutine": "// UNSUPPORTED: c++03, c++11, c++14, c++17",
diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py
index 4076379c41276..4aff04864e2d1 100644
--- a/libcxx/utils/libcxx/test/modules.py
+++ b/libcxx/utils/libcxx/test/modules.py
@@ -7,7 +7,6 @@
 # ===----------------------------------------------------------------------===##
 
 from libcxx.header_information import module_headers
-from libcxx.header_information import header_restrictions
 from dataclasses import dataclass
 
 ### SkipDeclarations
@@ -141,15 +140,7 @@ def process_module_partition(self, header, is_c_header):
         # Some headers cannot be included when a libc++ feature is disabled.
         # In that case include the header conditionally. The header __config
         # ensures the libc++ feature macros are available.
-        if header in header_restrictions:
-            include = (
-                f"#include <__config>{nl}"
-                f"#if {header_restrictions[header]}{nl}"
-                f"#  include <{header}>{nl}"
-                f"#endif{nl}"
-            )
-        else:
-            include = f"#include <{header}>{nl}"
+        include = f"#include <{header}>{nl}"
 
         module_files = f'#include \\"{self.module_path}/std/{header}.inc\\"{nl}'
         if is_c_header:



More information about the libcxx-commits mailing list