[libcxx-commits] [libcxx] 385cc25 - [libc++] Ensure that all public C++ headers include <__assert>

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 30 12:05:40 PDT 2022


Author: Louis Dionne
Date: 2022-03-30T15:05:31-04:00
New Revision: 385cc25a531a72c393cee44689e2c3194615bcec

URL: https://github.com/llvm/llvm-project/commit/385cc25a531a72c393cee44689e2c3194615bcec
DIFF: https://github.com/llvm/llvm-project/commit/385cc25a531a72c393cee44689e2c3194615bcec.diff

LOG: [libc++] Ensure that all public C++ headers include <__assert>

This patch changes the requirement for getting the declaration of the
assertion handler from including <__assert> to including any public
C++ header of the library. Note that C compatibility headers are
excluded because we don't implement all the C headers ourselves --
some of them are taken straight from the C library, like assert.h.

It also adds a generated test to check it. Furthermore, this new
generated test is designed in a way that will make it possible to
replace almost all the existing test-generation scripts with this
system in upcoming patches.

Differential Revision: https://reviews.llvm.org/D122506

Added: 
    libcxx/test/libcxx/assertions/headers_declare_assertion_handler.sh.cpp
    libcxx/utils/generate_assertion_tests.py

Modified: 
    libcxx/docs/UsingLibcxx.rst
    libcxx/include/algorithm
    libcxx/include/any
    libcxx/include/array
    libcxx/include/atomic
    libcxx/include/barrier
    libcxx/include/bit
    libcxx/include/bitset
    libcxx/include/cassert
    libcxx/include/ccomplex
    libcxx/include/cctype
    libcxx/include/cerrno
    libcxx/include/cfenv
    libcxx/include/cfloat
    libcxx/include/charconv
    libcxx/include/chrono
    libcxx/include/cinttypes
    libcxx/include/ciso646
    libcxx/include/climits
    libcxx/include/clocale
    libcxx/include/cmath
    libcxx/include/codecvt
    libcxx/include/compare
    libcxx/include/complex
    libcxx/include/concepts
    libcxx/include/condition_variable
    libcxx/include/coroutine
    libcxx/include/csetjmp
    libcxx/include/csignal
    libcxx/include/cstdarg
    libcxx/include/cstdbool
    libcxx/include/cstddef
    libcxx/include/cstdint
    libcxx/include/cstdio
    libcxx/include/cstdlib
    libcxx/include/cstring
    libcxx/include/ctgmath
    libcxx/include/ctime
    libcxx/include/cuchar
    libcxx/include/cwchar
    libcxx/include/cwctype
    libcxx/include/deque
    libcxx/include/exception
    libcxx/include/execution
    libcxx/include/experimental/algorithm
    libcxx/include/experimental/coroutine
    libcxx/include/experimental/deque
    libcxx/include/experimental/forward_list
    libcxx/include/experimental/functional
    libcxx/include/experimental/iterator
    libcxx/include/experimental/list
    libcxx/include/experimental/map
    libcxx/include/experimental/memory_resource
    libcxx/include/experimental/propagate_const
    libcxx/include/experimental/regex
    libcxx/include/experimental/set
    libcxx/include/experimental/simd
    libcxx/include/experimental/string
    libcxx/include/experimental/type_traits
    libcxx/include/experimental/unordered_map
    libcxx/include/experimental/unordered_set
    libcxx/include/experimental/utility
    libcxx/include/experimental/vector
    libcxx/include/ext/hash_map
    libcxx/include/ext/hash_set
    libcxx/include/filesystem
    libcxx/include/format
    libcxx/include/forward_list
    libcxx/include/fstream
    libcxx/include/functional
    libcxx/include/future
    libcxx/include/initializer_list
    libcxx/include/iomanip
    libcxx/include/ios
    libcxx/include/iosfwd
    libcxx/include/iostream
    libcxx/include/istream
    libcxx/include/iterator
    libcxx/include/latch
    libcxx/include/limits
    libcxx/include/list
    libcxx/include/locale
    libcxx/include/map
    libcxx/include/memory
    libcxx/include/mutex
    libcxx/include/new
    libcxx/include/numbers
    libcxx/include/numeric
    libcxx/include/optional
    libcxx/include/ostream
    libcxx/include/queue
    libcxx/include/random
    libcxx/include/ranges
    libcxx/include/ratio
    libcxx/include/regex
    libcxx/include/scoped_allocator
    libcxx/include/semaphore
    libcxx/include/set
    libcxx/include/shared_mutex
    libcxx/include/span
    libcxx/include/sstream
    libcxx/include/stack
    libcxx/include/stdbool.h
    libcxx/include/stdexcept
    libcxx/include/streambuf
    libcxx/include/string
    libcxx/include/string_view
    libcxx/include/strstream
    libcxx/include/system_error
    libcxx/include/thread
    libcxx/include/tuple
    libcxx/include/type_traits
    libcxx/include/typeindex
    libcxx/include/typeinfo
    libcxx/include/unordered_map
    libcxx/include/unordered_set
    libcxx/include/utility
    libcxx/include/valarray
    libcxx/include/variant
    libcxx/include/vector
    libcxx/include/version
    libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp
    libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
    libcxx/test/libcxx/assertions/customize_handler.pass.cpp
    libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
    libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp
    libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp
    libcxx/utils/CMakeLists.txt
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 3eab44abe8e95..0d7e3a99028f8 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -169,7 +169,7 @@ and ``operator delete``. For example:
 .. code-block:: cpp
 
   // In HelloWorldHandler.cpp
-  #include <__assert> // must include <__assert> before defining the handler
+  #include <version> // must include any libc++ header before defining the handler (C compatibility headers excluded)
 
   void std::__libcpp_assertion_handler(char const* file, int line, char const* expression, char const* message) {
     std::printf("Assertion %s failed at %s:%d, more info: %s", expression, file, line, message);

diff  --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 51a1781450fe2..c199c5a0c73f6 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -733,6 +733,7 @@ template <class BidirectionalIterator, class Compare>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__bits>
 #include <__config>
 #include <__debug>

diff  --git a/libcxx/include/any b/libcxx/include/any
index fc1641f6e0cd0..bd0ea5677d841 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -80,6 +80,7 @@ namespace std {
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <__utility/forward.h>

diff  --git a/libcxx/include/array b/libcxx/include/array
index 0b366080eefca..786dc75746695 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -112,7 +112,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
 #include <__algorithm/fill_n.h>
 #include <__algorithm/lexicographical_compare.h>
 #include <__algorithm/swap_ranges.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__tuple>
 #include <__utility/integer_sequence.h>

diff  --git a/libcxx/include/atomic b/libcxx/include/atomic
index dfa01bf239f86..b5c6e5182a4f2 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -518,6 +518,7 @@ template <class T>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__chrono/duration.h>
 #include <__config>

diff  --git a/libcxx/include/barrier b/libcxx/include/barrier
index 0382f2f8277b4..6f8a1f9f38be3 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -45,6 +45,7 @@ namespace std
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <__thread/timed_backoff_policy.h>

diff  --git a/libcxx/include/bit b/libcxx/include/bit
index aaefd8a362cfa..b73c4b44c8628 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -61,7 +61,7 @@ namespace std {
 
 */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__bit/bit_cast.h>
 #include <__bit/byteswap.h>
 #include <__bits> // __libcpp_clz

diff  --git a/libcxx/include/bitset b/libcxx/include/bitset
index 07c9494d2e199..28862d8ed660a 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -113,6 +113,7 @@ template <size_t N> struct hash<std::bitset<N>>;
 */
 
 #include <__algorithm/fill.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__bit_reference>
 #include <__config>
 #include <__functional/unary_function.h>

diff  --git a/libcxx/include/cassert b/libcxx/include/cassert
index 3c5bb7b110586..28fc0b10e9f49 100644
--- a/libcxx/include/cassert
+++ b/libcxx/include/cassert
@@ -16,6 +16,7 @@ Macros:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <assert.h>
 

diff  --git a/libcxx/include/ccomplex b/libcxx/include/ccomplex
index f1037f2841861..cf05c7a910814 100644
--- a/libcxx/include/ccomplex
+++ b/libcxx/include/ccomplex
@@ -17,12 +17,11 @@
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <complex>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-// hh 080623 Created
-
 #endif // _LIBCPP_CCOMPLEX

diff  --git a/libcxx/include/cctype b/libcxx/include/cctype
index fc770cfba356e..248f8d98000ff 100644
--- a/libcxx/include/cctype
+++ b/libcxx/include/cctype
@@ -34,6 +34,7 @@ int toupper(int c);
 }  // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <ctype.h>
 

diff  --git a/libcxx/include/cerrno b/libcxx/include/cerrno
index 9946c855b5d7c..e9eacd35effe2 100644
--- a/libcxx/include/cerrno
+++ b/libcxx/include/cerrno
@@ -22,6 +22,7 @@ Macros:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <errno.h>
 

diff  --git a/libcxx/include/cfenv b/libcxx/include/cfenv
index e1aae2f009ec1..e42b46680d158 100644
--- a/libcxx/include/cfenv
+++ b/libcxx/include/cfenv
@@ -52,6 +52,7 @@ int feupdateenv(const fenv_t* envp);
 }  // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <fenv.h>
 

diff  --git a/libcxx/include/cfloat b/libcxx/include/cfloat
index ff806cef9c4d4..36a7c51cdda52 100644
--- a/libcxx/include/cfloat
+++ b/libcxx/include/cfloat
@@ -69,6 +69,7 @@ Macros:
     LDBL_TRUE_MIN       // C11
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <float.h>
 

diff  --git a/libcxx/include/charconv b/libcxx/include/charconv
index 3b766e6069662..ca717dc4a0463 100644
--- a/libcxx/include/charconv
+++ b/libcxx/include/charconv
@@ -77,7 +77,7 @@ namespace std {
 
 */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__bits>
 #include <__charconv/chars_format.h>

diff  --git a/libcxx/include/chrono b/libcxx/include/chrono
index 63558adbc4a00..c6efd33345ed0 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -694,6 +694,7 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 }  // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__chrono/calendar.h>
 #include <__chrono/convert_to_timespec.h>
 #include <__chrono/duration.h>

diff  --git a/libcxx/include/cinttypes b/libcxx/include/cinttypes
index 0674384b79d0d..a4cfe961cc55e 100644
--- a/libcxx/include/cinttypes
+++ b/libcxx/include/cinttypes
@@ -234,6 +234,7 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
 }  // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cstdint>
 #include <inttypes.h>

diff  --git a/libcxx/include/ciso646 b/libcxx/include/ciso646
index 1d859f08fac57..e0cd722495ed0 100644
--- a/libcxx/include/ciso646
+++ b/libcxx/include/ciso646
@@ -15,6 +15,7 @@
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/climits b/libcxx/include/climits
index c365ca79a46b8..16800a652f6d4 100644
--- a/libcxx/include/climits
+++ b/libcxx/include/climits
@@ -37,6 +37,7 @@ Macros:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <limits.h>
 

diff  --git a/libcxx/include/clocale b/libcxx/include/clocale
index 1c1f244d2a02d..8926042075325 100644
--- a/libcxx/include/clocale
+++ b/libcxx/include/clocale
@@ -34,6 +34,7 @@ lconv* localeconv();
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <locale.h>
 

diff  --git a/libcxx/include/cmath b/libcxx/include/cmath
index be5cbe362666e..2d22151684e00 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -304,6 +304,7 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <math.h>
 #include <type_traits>

diff  --git a/libcxx/include/codecvt b/libcxx/include/codecvt
index b9b38b3834237..d3a9486929f4e 100644
--- a/libcxx/include/codecvt
+++ b/libcxx/include/codecvt
@@ -54,6 +54,7 @@ class codecvt_utf8_utf16
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__locale>
 #include <version>

diff  --git a/libcxx/include/compare b/libcxx/include/compare
index 6f620e48f765e..6aa1abefd3efb 100644
--- a/libcxx/include/compare
+++ b/libcxx/include/compare
@@ -140,6 +140,7 @@ namespace std {
 }
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__compare/common_comparison_category.h>
 #include <__compare/compare_partial_order_fallback.h>
 #include <__compare/compare_strong_order_fallback.h>

diff  --git a/libcxx/include/complex b/libcxx/include/complex
index 8384ed897aa24..87a4e58724978 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -231,6 +231,7 @@ template<class T> complex<T> tanh (const complex<T>&);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cmath>
 #include <iosfwd>

diff  --git a/libcxx/include/concepts b/libcxx/include/concepts
index 99dbcf4561f24..301256ca7ef7e 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -129,6 +129,7 @@ namespace std {
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__concepts/arithmetic.h>
 #include <__concepts/assignable.h>
 #include <__concepts/boolean_testable.h>

diff  --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable
index 6da7246500463..dfcb7160565b7 100644
--- a/libcxx/include/condition_variable
+++ b/libcxx/include/condition_variable
@@ -106,6 +106,7 @@ public:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__mutex_base>
 #include <memory>

diff  --git a/libcxx/include/coroutine b/libcxx/include/coroutine
index 478f4723f9ad8..11b2863e66663 100644
--- a/libcxx/include/coroutine
+++ b/libcxx/include/coroutine
@@ -38,6 +38,7 @@ struct suspend_always;
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__coroutine/coroutine_handle.h>
 #include <__coroutine/coroutine_traits.h>

diff  --git a/libcxx/include/csetjmp b/libcxx/include/csetjmp
index 76cbaab4c3877..4f40bcbf61e9e 100644
--- a/libcxx/include/csetjmp
+++ b/libcxx/include/csetjmp
@@ -30,6 +30,7 @@ void longjmp(jmp_buf env, int val);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <setjmp.h>
 

diff  --git a/libcxx/include/csignal b/libcxx/include/csignal
index 19091cfaa2a58..81ca89091c1bc 100644
--- a/libcxx/include/csignal
+++ b/libcxx/include/csignal
@@ -39,6 +39,7 @@ int raise(int sig);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <signal.h>
 

diff  --git a/libcxx/include/cstdarg b/libcxx/include/cstdarg
index 7dd906866ae09..f36ade202b7a5 100644
--- a/libcxx/include/cstdarg
+++ b/libcxx/include/cstdarg
@@ -31,6 +31,7 @@ Types:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <stdarg.h>
 

diff  --git a/libcxx/include/cstdbool b/libcxx/include/cstdbool
index ef731c021a4ab..ce608033a22ce 100644
--- a/libcxx/include/cstdbool
+++ b/libcxx/include/cstdbool
@@ -19,6 +19,7 @@ Macros:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/cstddef b/libcxx/include/cstddef
index 57cecc7bd772a..2a8b686bf3888 100644
--- a/libcxx/include/cstddef
+++ b/libcxx/include/cstddef
@@ -33,6 +33,7 @@ Types:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <stddef.h>
 #include <version>

diff  --git a/libcxx/include/cstdint b/libcxx/include/cstdint
index cac715bf0afab..83cda947b4978 100644
--- a/libcxx/include/cstdint
+++ b/libcxx/include/cstdint
@@ -140,6 +140,7 @@ Types:
 }  // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <stdint.h>
 

diff  --git a/libcxx/include/cstdio b/libcxx/include/cstdio
index d5b748d86ef70..d191086a85da9 100644
--- a/libcxx/include/cstdio
+++ b/libcxx/include/cstdio
@@ -95,6 +95,7 @@ void perror(const char* s);
 }  // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <stdio.h>
 

diff  --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index 9fad7e10cca66..457c31f625d82 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -81,6 +81,7 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <stdlib.h>
 

diff  --git a/libcxx/include/cstring b/libcxx/include/cstring
index acf1c4d326801..37c92e149b8ff 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -56,6 +56,7 @@ size_t strlen(const char* s);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <string.h>
 

diff  --git a/libcxx/include/ctgmath b/libcxx/include/ctgmath
index 6237979be4906..bfcf2f98d470c 100644
--- a/libcxx/include/ctgmath
+++ b/libcxx/include/ctgmath
@@ -18,6 +18,7 @@
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <ccomplex>
 #include <cmath>
 

diff  --git a/libcxx/include/ctime b/libcxx/include/ctime
index 58856e88736c0..0c6e4dfd6f985 100644
--- a/libcxx/include/ctime
+++ b/libcxx/include/ctime
@@ -45,6 +45,7 @@ int timespec_get( struct timespec *ts, int base); // C++17
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <time.h>
 

diff  --git a/libcxx/include/cuchar b/libcxx/include/cuchar
index fec14929bd23f..a4ed585d1aeb3 100644
--- a/libcxx/include/cuchar
+++ b/libcxx/include/cuchar
@@ -34,6 +34,7 @@ size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <uchar.h>
 

diff  --git a/libcxx/include/cwchar b/libcxx/include/cwchar
index c4d85215a2be1..5c69ab2a7bb1e 100644
--- a/libcxx/include/cwchar
+++ b/libcxx/include/cwchar
@@ -102,6 +102,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cwctype>
 #include <wchar.h>

diff  --git a/libcxx/include/cwctype b/libcxx/include/cwctype
index b4434f62d4a63..429b00c2446d7 100644
--- a/libcxx/include/cwctype
+++ b/libcxx/include/cwctype
@@ -49,6 +49,7 @@ wctrans_t wctrans(const char* property);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cctype>
 #include <wctype.h>

diff  --git a/libcxx/include/deque b/libcxx/include/deque
index 184bae0fd971b..4b78d77e6c7d5 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -169,7 +169,7 @@ template <class T, class Allocator, class Predicate>
 #include <__algorithm/remove.h>
 #include <__algorithm/remove_if.h>
 #include <__algorithm/unwrap_iter.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__split_buffer>

diff  --git a/libcxx/include/exception b/libcxx/include/exception
index a60c8e61b3c42..412e02af38227 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -76,6 +76,7 @@ template <class E> void rethrow_if_nested(const E& e);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <__memory/addressof.h>

diff  --git a/libcxx/include/execution b/libcxx/include/execution
index f4693329c93f4..040297038637f 100644
--- a/libcxx/include/execution
+++ b/libcxx/include/execution
@@ -10,6 +10,7 @@
 #ifndef _LIBCPP_EXECUTION
 #define _LIBCPP_EXECUTION
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <version>
 

diff  --git a/libcxx/include/experimental/algorithm b/libcxx/include/experimental/algorithm
index b9405bfe5ff95..e0ca3c73be6b1 100644
--- a/libcxx/include/experimental/algorithm
+++ b/libcxx/include/experimental/algorithm
@@ -31,6 +31,7 @@ ForwardIterator search(ForwardIterator first, ForwardIterator last,
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__debug>
 #include <algorithm>
 #include <experimental/__config>

diff  --git a/libcxx/include/experimental/coroutine b/libcxx/include/experimental/coroutine
index 837ab10766df4..e94450b1438ac 100644
--- a/libcxx/include/experimental/coroutine
+++ b/libcxx/include/experimental/coroutine
@@ -45,7 +45,7 @@ template <class P> struct hash<coroutine_handle<P>>;
 
  */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <cstddef>
 #include <experimental/__config>
 #include <functional>

diff  --git a/libcxx/include/experimental/deque b/libcxx/include/experimental/deque
index 1809991b4735f..3e3f9098a8fdf 100644
--- a/libcxx/include/experimental/deque
+++ b/libcxx/include/experimental/deque
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_DEQUE
 #define _LIBCPP_EXPERIMENTAL_DEQUE
+
 /*
     experimental/deque synopsis
 
@@ -28,6 +29,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <deque>
 #include <experimental/__config>
 #include <experimental/memory_resource>

diff  --git a/libcxx/include/experimental/forward_list b/libcxx/include/experimental/forward_list
index 675ae0656aa24..4b102c5547042 100644
--- a/libcxx/include/experimental/forward_list
+++ b/libcxx/include/experimental/forward_list
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_FORWARD_LIST
 #define _LIBCPP_EXPERIMENTAL_FORWARD_LIST
+
 /*
     experimental/forward_list synopsis
 
@@ -28,6 +29,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <forward_list>

diff  --git a/libcxx/include/experimental/functional b/libcxx/include/experimental/functional
index 1291894aa088f..0da5fced22eab 100644
--- a/libcxx/include/experimental/functional
+++ b/libcxx/include/experimental/functional
@@ -60,6 +60,7 @@ inline namespace fundamentals_v1 {
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__debug>
 #include <__memory/uses_allocator.h>
 #include <array>

diff  --git a/libcxx/include/experimental/iterator b/libcxx/include/experimental/iterator
index 137b206354f5b..79c594fde42b4 100644
--- a/libcxx/include/experimental/iterator
+++ b/libcxx/include/experimental/iterator
@@ -52,6 +52,7 @@ namespace std {
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__memory/addressof.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>

diff  --git a/libcxx/include/experimental/list b/libcxx/include/experimental/list
index d15d816444e34..c8480575977ec 100644
--- a/libcxx/include/experimental/list
+++ b/libcxx/include/experimental/list
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_LIST
 #define _LIBCPP_EXPERIMENTAL_LIST
+
 /*
     experimental/list synopsis
 
@@ -28,6 +29,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <list>

diff  --git a/libcxx/include/experimental/map b/libcxx/include/experimental/map
index 25bc56ccb4d1d..3dee7f703aeb5 100644
--- a/libcxx/include/experimental/map
+++ b/libcxx/include/experimental/map
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_MAP
 #define _LIBCPP_EXPERIMENTAL_MAP
+
 /*
     experimental/map synopsis
 
@@ -33,6 +34,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <map>

diff  --git a/libcxx/include/experimental/memory_resource b/libcxx/include/experimental/memory_resource
index 16c7d8de66c54..f7b19aafd40f5 100644
--- a/libcxx/include/experimental/memory_resource
+++ b/libcxx/include/experimental/memory_resource
@@ -64,7 +64,7 @@ namespace pmr {
 
  */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__tuple>
 #include <__utility/move.h>
 #include <cstddef>

diff  --git a/libcxx/include/experimental/propagate_const b/libcxx/include/experimental/propagate_const
index e6224225e3b16..7c9b783f4163c 100644
--- a/libcxx/include/experimental/propagate_const
+++ b/libcxx/include/experimental/propagate_const
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
 #define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
+
 /*
     propagate_const synopsis
 
@@ -106,6 +107,7 @@
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__utility/move.h>
 #include <__utility/swap.h>
 #include <experimental/__config>

diff  --git a/libcxx/include/experimental/regex b/libcxx/include/experimental/regex
index f108d2e8d0c4c..4dc2bbae45103 100644
--- a/libcxx/include/experimental/regex
+++ b/libcxx/include/experimental/regex
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_REGEX
 #define _LIBCPP_EXPERIMENTAL_REGEX
+
 /*
     experimental/regex synopsis
 
@@ -35,6 +36,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <experimental/string>

diff  --git a/libcxx/include/experimental/set b/libcxx/include/experimental/set
index 208952cb44d18..e2e75e35448ba 100644
--- a/libcxx/include/experimental/set
+++ b/libcxx/include/experimental/set
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_SET
 #define _LIBCPP_EXPERIMENTAL_SET
+
 /*
     experimental/set synopsis
 
@@ -33,6 +34,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <set>

diff  --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd
index 93d39c872bc9c..7fa185f4f3955 100644
--- a/libcxx/include/experimental/simd
+++ b/libcxx/include/experimental/simd
@@ -649,6 +649,7 @@ public:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <array>
 #include <cstddef>
 #include <experimental/__config>

diff  --git a/libcxx/include/experimental/string b/libcxx/include/experimental/string
index aab916778f8ae..c795d685d7351 100644
--- a/libcxx/include/experimental/string
+++ b/libcxx/include/experimental/string
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_STRING
 #define _LIBCPP_EXPERIMENTAL_STRING
+
 /*
     experimental/string synopsis
 
@@ -37,6 +38,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <string>

diff  --git a/libcxx/include/experimental/type_traits b/libcxx/include/experimental/type_traits
index 707cbde991256..dd4c539636407 100644
--- a/libcxx/include/experimental/type_traits
+++ b/libcxx/include/experimental/type_traits
@@ -68,6 +68,7 @@ inline namespace fundamentals_v1 {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 
 #if _LIBCPP_STD_VER > 11

diff  --git a/libcxx/include/experimental/unordered_map b/libcxx/include/experimental/unordered_map
index 069ba203d5b04..71ce4408c49f4 100644
--- a/libcxx/include/experimental/unordered_map
+++ b/libcxx/include/experimental/unordered_map
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_UNORDERED_MAP
 #define _LIBCPP_EXPERIMENTAL_UNORDERED_MAP
+
 /*
     experimental/unordered_map synopsis
 
@@ -39,6 +40,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <unordered_map>

diff  --git a/libcxx/include/experimental/unordered_set b/libcxx/include/experimental/unordered_set
index cac6c76414ba6..509f3ec1044ea 100644
--- a/libcxx/include/experimental/unordered_set
+++ b/libcxx/include/experimental/unordered_set
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_UNORDERED_SET
 #define _LIBCPP_EXPERIMENTAL_UNORDERED_SET
+
 /*
     experimental/unordered_set synopsis
 
@@ -33,6 +34,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <unordered_set>

diff  --git a/libcxx/include/experimental/utility b/libcxx/include/experimental/utility
index 21650a8d1ec10..576b8be463571 100644
--- a/libcxx/include/experimental/utility
+++ b/libcxx/include/experimental/utility
@@ -30,6 +30,7 @@ inline namespace fundamentals_v1 {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <utility>
 

diff  --git a/libcxx/include/experimental/vector b/libcxx/include/experimental/vector
index 1eb792758f4f9..97c51c830c4a2 100644
--- a/libcxx/include/experimental/vector
+++ b/libcxx/include/experimental/vector
@@ -9,6 +9,7 @@
 
 #ifndef _LIBCPP_EXPERIMENTAL_VECTOR
 #define _LIBCPP_EXPERIMENTAL_VECTOR
+
 /*
     experimental/vector synopsis
 
@@ -28,6 +29,7 @@ namespace pmr {
 
  */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <experimental/__config>
 #include <experimental/memory_resource>
 #include <vector>

diff  --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index 1816626c977c7..92572c08c24cc 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -201,9 +201,10 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 
 */
 
-#include <__algorithm/is_permutation.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__hash_table>
+#include <algorithm>
 #include <ext/__hash>
 #include <functional>
 #include <stdexcept>

diff  --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set
index cbd621b3bd6f6..eb61939406682 100644
--- a/libcxx/include/ext/hash_set
+++ b/libcxx/include/ext/hash_set
@@ -192,9 +192,10 @@ template <class Value, class Hash, class Pred, class Alloc>
 
 */
 
-#include <__algorithm/is_permutation.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__hash_table>
+#include <algorithm>
 #include <ext/__hash>
 #include <functional>
 

diff  --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index afb75df574918..c23cac9828b18 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 #ifndef _LIBCPP_FILESYSTEM
 #define _LIBCPP_FILESYSTEM
+
 /*
     filesystem synopsis
 
@@ -238,6 +239,7 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__filesystem/copy_options.h>
 #include <__filesystem/directory_entry.h>

diff  --git a/libcxx/include/format b/libcxx/include/format
index 5ff62c3f0fa65..6cefab4948d22 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -117,6 +117,7 @@ namespace std {
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 // Make sure all feature-test macros are available.
 #include <version>
 // Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.

diff  --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 4b3f4e2ec8267..23c1229e7b5c7 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -182,6 +182,7 @@ template <class T, class Allocator, class Predicate>
 #include <__algorithm/comp.h>
 #include <__algorithm/lexicographical_compare.h>
 #include <__algorithm/min.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__utility/forward.h>
 #include <initializer_list>

diff  --git a/libcxx/include/fstream b/libcxx/include/fstream
index 2f1cd32b35fb1..907c59e888fb0 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -180,7 +180,7 @@ typedef basic_fstream<wchar_t> wfstream;
 */
 
 #include <__algorithm/max.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <__locale>

diff  --git a/libcxx/include/functional b/libcxx/include/functional
index d097861a9011d..7430551c65783 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -491,6 +491,7 @@ POLICY:  For non-variadic implementations, the number of arguments is limited
 */
 
 #include <__algorithm/search.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__compare/compare_three_way.h>
 #include <__config>
 #include <__debug>

diff  --git a/libcxx/include/future b/libcxx/include/future
index 162d400136027..b39747792261d 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -361,7 +361,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
 
 */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__chrono/duration.h>
 #include <__chrono/time_point.h>

diff  --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
index e61318e64efe4..02a8ec57fab3a 100644
--- a/libcxx/include/initializer_list
+++ b/libcxx/include/initializer_list
@@ -42,6 +42,7 @@ template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cstddef>
 

diff  --git a/libcxx/include/iomanip b/libcxx/include/iomanip
index c4d8351926b66..69b55be7cc153 100644
--- a/libcxx/include/iomanip
+++ b/libcxx/include/iomanip
@@ -42,6 +42,7 @@ template <class charT, class traits, class Allocator>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__string>
 #include <istream>

diff  --git a/libcxx/include/ios b/libcxx/include/ios
index 15053e524682a..a790ba5c17758 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -210,6 +210,7 @@ storage-class-specifier const error_category& iostream_category() noexcept;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__ios/fpos.h>
 #include <__locale>

diff  --git a/libcxx/include/iosfwd b/libcxx/include/iosfwd
index 263a66771fb3c..6cb55868c6be4 100644
--- a/libcxx/include/iosfwd
+++ b/libcxx/include/iosfwd
@@ -94,6 +94,7 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__mbstate_t.h>
 #include <version>

diff  --git a/libcxx/include/iostream b/libcxx/include/iostream
index 10d17d6b42274..b5aef3efaa596 100644
--- a/libcxx/include/iostream
+++ b/libcxx/include/iostream
@@ -33,6 +33,7 @@ extern wostream wclog;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <ios>
 #include <istream>

diff  --git a/libcxx/include/istream b/libcxx/include/istream
index 8259c5252b2a2..201339ff4db42 100644
--- a/libcxx/include/istream
+++ b/libcxx/include/istream
@@ -158,6 +158,7 @@ template <class Stream, class T>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__utility/forward.h>
 #include <ostream>

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 8ba4d0ccb17cf..4060c2d9d4fd0 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -634,6 +634,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__iterator/access.h>

diff  --git a/libcxx/include/latch b/libcxx/include/latch
index 7df7fdaa85a0b..d6cb47622268b 100644
--- a/libcxx/include/latch
+++ b/libcxx/include/latch
@@ -40,6 +40,7 @@ namespace std
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <atomic>

diff  --git a/libcxx/include/limits b/libcxx/include/limits
index 5afef4bd7e064..35e4d85734dea 100644
--- a/libcxx/include/limits
+++ b/libcxx/include/limits
@@ -101,6 +101,8 @@ template<> class numeric_limits<cv long double>;
 }  // std
 
 */
+
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <type_traits>
 

diff  --git a/libcxx/include/list b/libcxx/include/list
index 31cacbc71d3ad..c3337d4588350 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -184,7 +184,7 @@ template <class T, class Allocator, class Predicate>
 #include <__algorithm/equal.h>
 #include <__algorithm/lexicographical_compare.h>
 #include <__algorithm/min.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__utility/forward.h>

diff  --git a/libcxx/include/locale b/libcxx/include/locale
index 067c146d8234d..8ff7567d865ed 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -192,7 +192,7 @@ template <class charT> class messages_byname;
 #include <__algorithm/max.h>
 #include <__algorithm/reverse.h>
 #include <__algorithm/unwrap_iter.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__locale>

diff  --git a/libcxx/include/map b/libcxx/include/map
index 8d26cdba17bd4..7371d5182c0db 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -530,7 +530,7 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
 
 #include <__algorithm/equal.h>
 #include <__algorithm/lexicographical_compare.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__functional/is_transparent.h>
 #include <__iterator/iterator_traits.h>

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 1991e29228d16..53172c58c3b4a 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -804,6 +804,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__memory/addressof.h>
 #include <__memory/allocation_guard.h>

diff  --git a/libcxx/include/mutex b/libcxx/include/mutex
index 536cf9c6ead01..a94e3b7daef92 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -186,6 +186,7 @@ template<class Callable, class ...Args>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__mutex_base>
 #include <__threading_support>

diff  --git a/libcxx/include/new b/libcxx/include/new
index 0d8d43e8d3caa..e91a42253d5b4 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -86,6 +86,7 @@ void  operator delete[](void* ptr, void*) noexcept;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <cstddef>

diff  --git a/libcxx/include/numbers b/libcxx/include/numbers
index 22b185aeae6e6..3c8527dfc2de1 100644
--- a/libcxx/include/numbers
+++ b/libcxx/include/numbers
@@ -58,6 +58,7 @@ namespace std::numbers {
 }
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <concepts>
 #include <type_traits>

diff  --git a/libcxx/include/numeric b/libcxx/include/numeric
index c8c6bced0a12a..ef963365ae71d 100644
--- a/libcxx/include/numeric
+++ b/libcxx/include/numeric
@@ -144,6 +144,7 @@ template<class T>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cmath> // for isnormal
 #include <functional>

diff  --git a/libcxx/include/optional b/libcxx/include/optional
index 22b0cf16cdc7f..8dc1a136fdafc 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -158,7 +158,7 @@ template<class T>
 
 */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__concepts/invocable.h>
 #include <__config>

diff  --git a/libcxx/include/ostream b/libcxx/include/ostream
index 3587c359a46c9..702f505d4f345 100644
--- a/libcxx/include/ostream
+++ b/libcxx/include/ostream
@@ -134,6 +134,7 @@ template <class Stream, class T>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <bitset>
 #include <ios>

diff  --git a/libcxx/include/queue b/libcxx/include/queue
index b8b7ec46d9568..d15c141920e8e 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -220,6 +220,7 @@ template <class T, class Container, class Compare>
 #include <__algorithm/make_heap.h>
 #include <__algorithm/pop_heap.h>
 #include <__algorithm/push_heap.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__memory/uses_allocator.h>

diff  --git a/libcxx/include/random b/libcxx/include/random
index 0323c447618cb..a2e1719b86213 100644
--- a/libcxx/include/random
+++ b/libcxx/include/random
@@ -1677,6 +1677,7 @@ class piecewise_linear_distribution
 } // std
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__random/bernoulli_distribution.h>
 #include <__random/binomial_distribution.h>

diff  --git a/libcxx/include/ranges b/libcxx/include/ranges
index b6c028d2219b6..5be1614d3b11d 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -230,6 +230,7 @@ namespace std {
 }
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__ranges/access.h>
 #include <__ranges/all.h>

diff  --git a/libcxx/include/ratio b/libcxx/include/ratio
index 07376bf8d7134..5d7af88a2ac8d 100644
--- a/libcxx/include/ratio
+++ b/libcxx/include/ratio
@@ -77,6 +77,7 @@ typedef ratio<1000000000000000000000000, 1> yotta;  // not supported
 }
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <climits>
 #include <cstdint>

diff  --git a/libcxx/include/regex b/libcxx/include/regex
index 661a08b7c30c7..456f34d451779 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -763,7 +763,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 */
 
 #include <__algorithm/find.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__iterator/wrap_iter.h>
 #include <__locale>

diff  --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator
index fe6d606ad14f2..b505aad9dcf78 100644
--- a/libcxx/include/scoped_allocator
+++ b/libcxx/include/scoped_allocator
@@ -109,6 +109,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__utility/forward.h>
 #include <memory>

diff  --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index df7b0d921e1ee..b174eba34dbcd 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -45,6 +45,7 @@ using binary_semaphore = counting_semaphore<1>;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__chrono/time_point.h>
 #include <__config>

diff  --git a/libcxx/include/set b/libcxx/include/set
index 1ac86a1b26fd3..a2d43cd883e35 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -473,7 +473,7 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);  // C++20
 
 #include <__algorithm/equal.h>
 #include <__algorithm/lexicographical_compare.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__functional/is_transparent.h>
 #include <__iterator/iterator_traits.h>

diff  --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 95aa37806634b..68a2bbae0f53a 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -122,6 +122,7 @@ template <class Mutex>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <version>

diff  --git a/libcxx/include/span b/libcxx/include/span
index adb7d000488d0..b96466550e8fa 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -127,7 +127,7 @@ template<class R>
 
 */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__iterator/concepts.h>

diff  --git a/libcxx/include/sstream b/libcxx/include/sstream
index ba6148be8bd55..4ab3af74f05df 100644
--- a/libcxx/include/sstream
+++ b/libcxx/include/sstream
@@ -180,6 +180,7 @@ typedef basic_stringstream<wchar_t> wstringstream;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__utility/swap.h>
 #include <istream>

diff  --git a/libcxx/include/stack b/libcxx/include/stack
index 87d85c440a201..7405896001643 100644
--- a/libcxx/include/stack
+++ b/libcxx/include/stack
@@ -98,6 +98,7 @@ template <class T, class Container>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__memory/uses_allocator.h>

diff  --git a/libcxx/include/stdbool.h b/libcxx/include/stdbool.h
index 369f8b3d0825a..0bc1aa8304adc 100644
--- a/libcxx/include/stdbool.h
+++ b/libcxx/include/stdbool.h
@@ -9,7 +9,6 @@
 #ifndef _LIBCPP_STDBOOL_H
 #define _LIBCPP_STDBOOL_H
 
-
 /*
     stdbool.h synopsis
 

diff  --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept
index f6dcf5ffeabf9..ee5a296cd9305 100644
--- a/libcxx/include/stdexcept
+++ b/libcxx/include/stdexcept
@@ -41,6 +41,7 @@ public:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cstdlib>
 #include <exception>

diff  --git a/libcxx/include/streambuf b/libcxx/include/streambuf
index abcdfe2e2fde3..d76f6d0379efe 100644
--- a/libcxx/include/streambuf
+++ b/libcxx/include/streambuf
@@ -107,6 +107,7 @@ protected:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cstdint>
 #include <ios>

diff  --git a/libcxx/include/string b/libcxx/include/string
index c79c0ed72abd8..60b40c369b691 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -522,7 +522,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1
 #include <__algorithm/min.h>
 #include <__algorithm/remove.h>
 #include <__algorithm/remove_if.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__ios/fpos.h>

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index 0b2456d939501..7c5d52b877d1c 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -11,7 +11,8 @@
 #define _LIBCPP_STRING_VIEW
 
 /*
-string_view synopsis
+
+    string_view synopsis
 
 namespace std {
 
@@ -196,7 +197,7 @@ namespace std {
 */
 
 #include <__algorithm/min.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__ranges/concepts.h>
 #include <__ranges/data.h>

diff  --git a/libcxx/include/strstream b/libcxx/include/strstream
index 1904bb773f7b5..9ffdd9f84a317 100644
--- a/libcxx/include/strstream
+++ b/libcxx/include/strstream
@@ -129,6 +129,7 @@ private:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <istream>
 #include <ostream>

diff  --git a/libcxx/include/system_error b/libcxx/include/system_error
index 48a6b2e503f1d..feffa2debf4e0 100644
--- a/libcxx/include/system_error
+++ b/libcxx/include/system_error
@@ -142,6 +142,7 @@ template <> struct hash<std::error_condition>;
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__errc>
 #include <__functional/unary_function.h>

diff  --git a/libcxx/include/thread b/libcxx/include/thread
index 5a8e830fcca73..540f591f9d131 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -82,7 +82,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
 
 */
 
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__mutex_base>
 #include <__thread/poll_with_backoff.h>

diff  --git a/libcxx/include/tuple b/libcxx/include/tuple
index ea7245d7aa88a..0a62578eadbbd 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -165,6 +165,7 @@ template <class... Types>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__compare/common_comparison_category.h>
 #include <__compare/synth_three_way.h>
 #include <__config>

diff  --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 0ecb0f97205b1..952f5787baae3 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -416,6 +416,8 @@ namespace std
 }
 
 */
+
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cstddef>
 #include <version>

diff  --git a/libcxx/include/typeindex b/libcxx/include/typeindex
index f0680398e9a15..0b61f28b96eba 100644
--- a/libcxx/include/typeindex
+++ b/libcxx/include/typeindex
@@ -44,6 +44,7 @@ struct hash<type_index>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__functional/unary_function.h>
 #include <compare>

diff  --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo
index 3d23458ef32f0..a0ac527db7823 100644
--- a/libcxx/include/typeinfo
+++ b/libcxx/include/typeinfo
@@ -56,6 +56,7 @@ public:
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <cstddef>

diff  --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index c701e67b2ef46..b7acfc3c8d00e 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -515,7 +515,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 */
 
 #include <__algorithm/is_permutation.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__functional/is_transparent.h>

diff  --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 0dd53a298ea63..f4ec9f5d5e1c5 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -460,7 +460,7 @@ template <class Value, class Hash, class Pred, class Alloc>
 */
 
 #include <__algorithm/is_permutation.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__debug>
 #include <__functional/is_transparent.h>

diff  --git a/libcxx/include/utility b/libcxx/include/utility
index ab19e2bc6f77c..bcd4abfcd1114 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -220,8 +220,8 @@ template <class T>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <__debug>
 #include <__tuple>
 #include <__utility/as_const.h>
 #include <__utility/auto_cast.h>

diff  --git a/libcxx/include/valarray b/libcxx/include/valarray
index 8ceaafeb35bdb..d79b0b21da069 100644
--- a/libcxx/include/valarray
+++ b/libcxx/include/valarray
@@ -348,6 +348,7 @@ template <class T> unspecified2 end(const valarray<T>& v);
 #include <__algorithm/min.h>
 #include <__algorithm/min_element.h>
 #include <__algorithm/unwrap_iter.h>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cmath>
 #include <cstddef>

diff  --git a/libcxx/include/variant b/libcxx/include/variant
index 3c68ab2cbc2bf..6012aaad1f297 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -199,6 +199,7 @@ namespace std {
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__availability>
 #include <__config>
 #include <__functional/hash.h>

diff  --git a/libcxx/include/vector b/libcxx/include/vector
index ba4c1b4396719..064a99d2f5de0 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -279,7 +279,7 @@ erase_if(vector<T, Allocator>& c, Predicate pred);    // C++20
 #include <__algorithm/remove_if.h>
 #include <__algorithm/rotate.h>
 #include <__algorithm/unwrap_iter.h>
-#include <__assert>
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__bit_reference>
 #include <__config>
 #include <__debug>

diff  --git a/libcxx/include/version b/libcxx/include/version
index 1fbba7ea74187..003a42cf59e6a 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -193,6 +193,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp b/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp
index 52dd7856e473b..5ec5f12fc2854 100644
--- a/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp
+++ b/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp
@@ -12,7 +12,6 @@
 
 // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=0
 
-#include <__assert>
 #include <cassert>
 
 bool executed_condition = false;

diff  --git a/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp b/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
index 59b56d328a716..fda41a595bb27 100644
--- a/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
+++ b/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
@@ -14,7 +14,6 @@
 
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 -D_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED
 
-#include <__assert>
 #include <cassert>
 
 bool handler_called = false;

diff  --git a/libcxx/test/libcxx/assertions/customize_handler.pass.cpp b/libcxx/test/libcxx/assertions/customize_handler.pass.cpp
index 2a0f26ab852db..5d6614114fbf3 100644
--- a/libcxx/test/libcxx/assertions/customize_handler.pass.cpp
+++ b/libcxx/test/libcxx/assertions/customize_handler.pass.cpp
@@ -14,7 +14,6 @@
 // failures when back-deploying.
 // UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}}
 
-#include <__assert>
 #include <cassert>
 
 bool handler_called = false;

diff  --git a/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp b/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
index 61ebb7b316bba..6a5c4e82163b7 100644
--- a/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
+++ b/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
@@ -16,7 +16,6 @@
 // failures when back-deploying.
 // UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}}
 
-#include <__assert>
 #include <cassert>
 
 bool handler_called = false;

diff  --git a/libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp b/libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp
index 5be0997d67407..4e1cb9e066582 100644
--- a/libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp
+++ b/libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp
@@ -14,7 +14,6 @@
 // failures when back-deploying.
 // UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}}
 
-#include <__assert>
 #include <csignal>
 #include <cstdlib>
 

diff  --git a/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp b/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp
index 93d6d020cb1fd..6fc8d1601aed7 100644
--- a/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp
+++ b/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp
@@ -13,7 +13,7 @@
 
 // REQUIRES: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}}
 
-#include <__assert>
+#include <version> // any header would work
 
 void f() {
   _LIBCPP_ASSERT(true, "message"); // expected-error {{'__libcpp_assertion_handler' is unavailable}}

diff  --git a/libcxx/test/libcxx/assertions/headers_declare_assertion_handler.sh.cpp b/libcxx/test/libcxx/assertions/headers_declare_assertion_handler.sh.cpp
new file mode 100644
index 0000000000000..0bdc30899b495
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/headers_declare_assertion_handler.sh.cpp
@@ -0,0 +1,769 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that all public C++ headers define the assertion handler.
+
+// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime
+// failures when back-deploying.
+// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}}
+
+// The system-provided <uchar.h> seems to be broken on AIX, which trips up this test.
+// XFAIL: LIBCXX-AIX-FIXME
+
+/*
+BEGIN-SCRIPT
+
+for i, header in enumerate(public_headers):
+    # Skip C compatibility headers.
+    if header.endswith('.h'):
+        continue
+
+    vars = {
+        'run': 'RUN',
+        'i': i,
+        'restrictions': ' && ' + header_restrictions[header] if header in header_restrictions else '',
+        'header': header
+    }
+
+    print("""\
+// {run}: %{{build}} -DTEST_{i}
+#if defined(TEST_{i}){restrictions}
+#   include <{header}>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+""".format(**vars))
+
+END-SCRIPT
+*/
+
+#include <__config>
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+#if defined(__DEPRECATED)
+#   undef __DEPRECATED
+#endif
+
+int main(int, char**) { return 0; }
+
+// DO NOT MANUALLY EDIT ANYTHING BETWEEN THE MARKERS BELOW
+// GENERATED-MARKER
+// RUN: %{build} -DTEST_0
+#if defined(TEST_0)
+#   include <algorithm>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_1
+#if defined(TEST_1)
+#   include <any>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_2
+#if defined(TEST_2)
+#   include <array>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_3
+#if defined(TEST_3)
+#   include <atomic>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_4
+#if defined(TEST_4) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <barrier>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_5
+#if defined(TEST_5)
+#   include <bit>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_6
+#if defined(TEST_6)
+#   include <bitset>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_7
+#if defined(TEST_7)
+#   include <cassert>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_8
+#if defined(TEST_8)
+#   include <ccomplex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_9
+#if defined(TEST_9)
+#   include <cctype>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_10
+#if defined(TEST_10)
+#   include <cerrno>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_11
+#if defined(TEST_11)
+#   include <cfenv>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_12
+#if defined(TEST_12)
+#   include <cfloat>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_13
+#if defined(TEST_13)
+#   include <charconv>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_14
+#if defined(TEST_14)
+#   include <chrono>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_15
+#if defined(TEST_15)
+#   include <cinttypes>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_16
+#if defined(TEST_16)
+#   include <ciso646>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_17
+#if defined(TEST_17)
+#   include <climits>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_18
+#if defined(TEST_18) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <clocale>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_19
+#if defined(TEST_19)
+#   include <cmath>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_20
+#if defined(TEST_20) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <codecvt>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_21
+#if defined(TEST_21)
+#   include <compare>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_22
+#if defined(TEST_22)
+#   include <complex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_24
+#if defined(TEST_24)
+#   include <concepts>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_25
+#if defined(TEST_25)
+#   include <condition_variable>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_26
+#if defined(TEST_26)
+#   include <coroutine>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_27
+#if defined(TEST_27)
+#   include <csetjmp>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_28
+#if defined(TEST_28)
+#   include <csignal>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_29
+#if defined(TEST_29)
+#   include <cstdarg>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_30
+#if defined(TEST_30)
+#   include <cstdbool>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_31
+#if defined(TEST_31)
+#   include <cstddef>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_32
+#if defined(TEST_32)
+#   include <cstdint>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_33
+#if defined(TEST_33)
+#   include <cstdio>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_34
+#if defined(TEST_34)
+#   include <cstdlib>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_35
+#if defined(TEST_35)
+#   include <cstring>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_36
+#if defined(TEST_36)
+#   include <ctgmath>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_37
+#if defined(TEST_37)
+#   include <ctime>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_39
+#if defined(TEST_39)
+#   include <cuchar>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_40
+#if defined(TEST_40) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+#   include <cwchar>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_41
+#if defined(TEST_41) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+#   include <cwctype>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_42
+#if defined(TEST_42)
+#   include <deque>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_44
+#if defined(TEST_44)
+#   include <exception>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_45
+#if defined(TEST_45)
+#   include <execution>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_47
+#if defined(TEST_47) && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
+#   include <filesystem>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_49
+#if defined(TEST_49)
+#   include <format>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_50
+#if defined(TEST_50)
+#   include <forward_list>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_51
+#if defined(TEST_51) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <fstream>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_52
+#if defined(TEST_52)
+#   include <functional>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_53
+#if defined(TEST_53) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <future>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_54
+#if defined(TEST_54)
+#   include <initializer_list>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_56
+#if defined(TEST_56) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <iomanip>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_57
+#if defined(TEST_57) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <ios>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_58
+#if defined(TEST_58)
+#   include <iosfwd>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_59
+#if defined(TEST_59) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <iostream>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_60
+#if defined(TEST_60) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <istream>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_61
+#if defined(TEST_61)
+#   include <iterator>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_62
+#if defined(TEST_62) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <latch>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_63
+#if defined(TEST_63)
+#   include <limits>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_65
+#if defined(TEST_65)
+#   include <list>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_66
+#if defined(TEST_66) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <locale>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_68
+#if defined(TEST_68)
+#   include <map>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_70
+#if defined(TEST_70)
+#   include <memory>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_71
+#if defined(TEST_71) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <mutex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_72
+#if defined(TEST_72)
+#   include <new>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_73
+#if defined(TEST_73)
+#   include <numbers>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_74
+#if defined(TEST_74)
+#   include <numeric>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_75
+#if defined(TEST_75)
+#   include <optional>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_76
+#if defined(TEST_76) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <ostream>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_77
+#if defined(TEST_77)
+#   include <queue>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_78
+#if defined(TEST_78)
+#   include <random>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_79
+#if defined(TEST_79)
+#   include <ranges>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_80
+#if defined(TEST_80)
+#   include <ratio>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_81
+#if defined(TEST_81) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <regex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_82
+#if defined(TEST_82)
+#   include <scoped_allocator>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_83
+#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <semaphore>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_84
+#if defined(TEST_84)
+#   include <set>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_86
+#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <shared_mutex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_87
+#if defined(TEST_87)
+#   include <span>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_88
+#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <sstream>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_89
+#if defined(TEST_89)
+#   include <stack>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_92
+#if defined(TEST_92)
+#   include <stdexcept>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_96
+#if defined(TEST_96) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <streambuf>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_97
+#if defined(TEST_97)
+#   include <string>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_99
+#if defined(TEST_99)
+#   include <string_view>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_100
+#if defined(TEST_100) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#   include <strstream>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_101
+#if defined(TEST_101)
+#   include <system_error>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_103
+#if defined(TEST_103) && !defined(_LIBCPP_HAS_NO_THREADS)
+#   include <thread>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_104
+#if defined(TEST_104)
+#   include <tuple>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_105
+#if defined(TEST_105)
+#   include <type_traits>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_106
+#if defined(TEST_106)
+#   include <typeindex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_107
+#if defined(TEST_107)
+#   include <typeinfo>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_109
+#if defined(TEST_109)
+#   include <unordered_map>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_110
+#if defined(TEST_110)
+#   include <unordered_set>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_111
+#if defined(TEST_111)
+#   include <utility>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_112
+#if defined(TEST_112)
+#   include <valarray>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_113
+#if defined(TEST_113)
+#   include <variant>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_114
+#if defined(TEST_114)
+#   include <vector>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_115
+#if defined(TEST_115)
+#   include <version>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_118
+#if defined(TEST_118)
+#   include <experimental/algorithm>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_119
+#if defined(TEST_119) && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
+#   include <experimental/coroutine>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_120
+#if defined(TEST_120) && __cplusplus >= 201103L
+#   include <experimental/deque>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_121
+#if defined(TEST_121) && __cplusplus >= 201103L
+#   include <experimental/forward_list>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_122
+#if defined(TEST_122)
+#   include <experimental/functional>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_123
+#if defined(TEST_123)
+#   include <experimental/iterator>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_124
+#if defined(TEST_124) && __cplusplus >= 201103L
+#   include <experimental/list>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_125
+#if defined(TEST_125) && __cplusplus >= 201103L
+#   include <experimental/map>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_126
+#if defined(TEST_126) && __cplusplus >= 201103L
+#   include <experimental/memory_resource>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_127
+#if defined(TEST_127)
+#   include <experimental/propagate_const>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_128
+#if defined(TEST_128) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
+#   include <experimental/regex>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_129
+#if defined(TEST_129) && __cplusplus >= 201103L
+#   include <experimental/set>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_130
+#if defined(TEST_130)
+#   include <experimental/simd>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_131
+#if defined(TEST_131) && __cplusplus >= 201103L
+#   include <experimental/string>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_132
+#if defined(TEST_132)
+#   include <experimental/type_traits>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_133
+#if defined(TEST_133) && __cplusplus >= 201103L
+#   include <experimental/unordered_map>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_134
+#if defined(TEST_134) && __cplusplus >= 201103L
+#   include <experimental/unordered_set>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_135
+#if defined(TEST_135)
+#   include <experimental/utility>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_136
+#if defined(TEST_136) && __cplusplus >= 201103L
+#   include <experimental/vector>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_137
+#if defined(TEST_137)
+#   include <ext/hash_map>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// RUN: %{build} -DTEST_138
+#if defined(TEST_138)
+#   include <ext/hash_set>
+    using HandlerType = decltype(std::__libcpp_assertion_handler);
+#endif
+
+// GENERATED-MARKER

diff  --git a/libcxx/utils/CMakeLists.txt b/libcxx/utils/CMakeLists.txt
index 4aefa89a9061e..d3379352fbba0 100644
--- a/libcxx/utils/CMakeLists.txt
+++ b/libcxx/utils/CMakeLists.txt
@@ -15,9 +15,14 @@ add_custom_target(libcxx-generate-private-header-tests
     COMMAND "${Python3_EXECUTABLE}" "${LIBCXX_SOURCE_DIR}/utils/generate_private_header_tests.py"
     COMMENT "Generate tests for ensuring that detail headers are private.")
 
+add_custom_target(libcxx-generate-assertion-tests
+    COMMAND "${Python3_EXECUTABLE}" "${LIBCXX_SOURCE_DIR}/utils/generate_assertion_tests.py"
+    COMMENT "Generate tests for inclusion of <__assert>.")
+
 add_custom_target(libcxx-generate-files
     DEPENDS libcxx-generate-public-header-transitive-inclusion-tests
             libcxx-generate-public-header-tests
             libcxx-generate-feature-test-macros
             libcxx-generate-private-header-tests
+            libcxx-generate-assertion-tests
     COMMENT "Create all the auto-generated files in libc++ and its tests.")

diff  --git a/libcxx/utils/generate_assertion_tests.py b/libcxx/utils/generate_assertion_tests.py
new file mode 100755
index 0000000000000..7ef30bc146a1e
--- /dev/null
+++ b/libcxx/utils/generate_assertion_tests.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+
+import contextlib
+import glob
+import io
+import os
+import pathlib
+import re
+
+header_restrictions = {
+    "barrier": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "future": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "latch": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "mutex": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "semaphore": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "shared_mutex": "!defined(_LIBCPP_HAS_NO_THREADS)",
+    "thread": "!defined(_LIBCPP_HAS_NO_THREADS)",
+
+    "filesystem": "!defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)",
+
+    "clocale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "codecvt": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "fstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "iomanip": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "ios": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "iostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "istream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "locale.h": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "locale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "ostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "regex": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "sstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "streambuf": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+    "strstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+
+    "wctype.h": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
+    "cwctype": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
+    "cwchar": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
+    "wchar.h": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
+
+    "experimental/coroutine": "!defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)",
+
+    "experimental/regex": "!defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L",
+    "experimental/deque": "__cplusplus >= 201103L",
+    "experimental/map": "__cplusplus >= 201103L",
+    "experimental/memory_resource": "__cplusplus >= 201103L",
+    "experimental/forward_list": "__cplusplus >= 201103L",
+    "experimental/list": "__cplusplus >= 201103L",
+    "experimental/set": "__cplusplus >= 201103L",
+    "experimental/string": "__cplusplus >= 201103L",
+    "experimental/unordered_map": "__cplusplus >= 201103L",
+    "experimental/unordered_set": "__cplusplus >= 201103L",
+    "experimental/vector": "__cplusplus >= 201103L",
+}
+
+private_headers_still_public_in_modules = [
+    '__assert', '__bsd_locale_defaults.h', '__bsd_locale_fallbacks.h', '__config',
+    '__config_site.in', '__debug', '__hash_table',
+    '__libcpp_version', '__threading_support', '__tree', '__undef_macros'
+]
+
+def find_script(file):
+    """Finds the script used to generate a file inside the file itself. The script is delimited by
+       BEGIN-SCRIPT and END-SCRIPT markers.
+    """
+    with open(file, 'r') as f:
+        content = f.read()
+
+    match = re.search(r'^BEGIN-SCRIPT$(.+)^END-SCRIPT$', content, flags=re.MULTILINE | re.DOTALL)
+    if not match:
+        raise RuntimeError("Was unable to find a script delimited with BEGIN-SCRIPT/END-SCRIPT markers in {}".format(test_file))
+    return match.group(1)
+
+def execute_script(script, variables):
+    """Executes the provided Mako template with the given variables available during the
+       evaluation of the script, and returns the result.
+    """
+    code = compile(script, 'fake-filename', 'exec')
+    output = io.StringIO()
+    with contextlib.redirect_stdout(output):
+        exec(code, variables)
+        output = output.getvalue()
+    return output
+
+def generate_new_file(file, new_content):
+    """Generates the new content of the file by inserting the new content in-between
+       two '// GENERATED-MARKER' markers located in the file.
+    """
+    with open(file, 'r') as f:
+        old_content = f.read()
+
+    try:
+        before, begin_marker, _, end_marker, after = re.split(r'(// GENERATED-MARKER\n)', old_content, flags=re.MULTILINE | re.DOTALL)
+    except ValueError:
+        raise RuntimeError("Failed to split {} based on markers, please make sure the file has exactly two '// GENERATED-MARKER' occurrences".format(file))
+
+    return before + begin_marker + new_content + end_marker + after
+
+def produce(test_file, variables):
+    script = find_script(test_file)
+    result = execute_script(script, variables)
+    new_content = generate_new_file(test_file, result)
+    with open(test_file, 'w', newline='\n') as f:
+        f.write(new_content)
+
+def is_header(file):
+    """Returns whether the given file is a header (i.e. not a directory or the modulemap file)."""
+    return not file.is_dir() and not file.name == 'module.modulemap'
+
+def main():
+    monorepo_root = pathlib.Path(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+    include = pathlib.Path(os.path.join(monorepo_root, 'libcxx', 'include'))
+    test = pathlib.Path(os.path.join(monorepo_root, 'libcxx', 'test'))
+    assert(monorepo_root.exists())
+
+    toplevel_headers     = sorted(str(p.relative_to(include)) for p in include.glob('[a-z]*') if is_header(p))
+    experimental_headers = sorted(str(p.relative_to(include)) for p in include.glob('experimental/[a-z]*') if is_header(p))
+    extended_headers     = sorted(str(p.relative_to(include)) for p in include.glob('ext/[a-z]*') if is_header(p))
+    public_headers       = toplevel_headers + experimental_headers + extended_headers
+    private_headers      = sorted(str(p.relative_to(include)) for p in include.rglob('*') if is_header(p) and str(p.relative_to(include)).startswith('__'))
+    variables = {
+        'toplevel_headers': toplevel_headers,
+        'experimental_headers': experimental_headers,
+        'extended_headers': extended_headers,
+        'public_headers': public_headers,
+        'private_headers': private_headers,
+        'header_restrictions': header_restrictions,
+        'private_headers_still_public_in_modules': private_headers_still_public_in_modules
+    }
+
+    produce(test.joinpath('libcxx/assertions/headers_declare_assertion_handler.sh.cpp'), variables)
+
+
+if __name__ == '__main__':
+    main()

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 14e5b4e44c589..191d0ee01cc9e 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -937,6 +937,7 @@ def produce_version_header():
 
 */
 
+#include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)


        


More information about the libcxx-commits mailing list