diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -55,7 +55,7 @@ available on the platform. This includes things like most parts of and others like " ON) option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS}) -set(LIBCXX_SUPPORTED_HARDENING_MODES unchecked hardened debug) +set(LIBCXX_SUPPORTED_HARDENING_MODES unchecked hardened safe debug) set(LIBCXX_HARDENING_MODE "unchecked" CACHE STRING "Specify the default hardening mode to use. This mode will be used inside the compiled library and will be the default when compiling user code. Note that @@ -759,18 +759,25 @@ config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) if (LIBCXX_HARDENING_MODE STREQUAL "hardened") config_define(1 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT) + config_define(0 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT) + config_define(0 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT) +elseif (LIBCXX_HARDENING_MODE STREQUAL "safe") + config_define(0 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT) + config_define(1 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT) config_define(0 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT) elseif (LIBCXX_HARDENING_MODE STREQUAL "debug") config_define(0 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT) + config_define(0 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT) config_define(1 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT) elseif (LIBCXX_HARDENING_MODE STREQUAL "unchecked") config_define(0 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT) + config_define(0 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT) config_define(0 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT) endif() # TODO(LLVM 18): Remove this after branching for LLVM 17, this is a simple # courtesy for vendors to be notified about this change. if (LIBCXX_ENABLE_ASSERTIONS) - message(FATAL_ERROR "LIBCXX_ENABLE_ASSERTIONS has been replaced by LIBCXX_HARDENING_MODE=hardened") + message(FATAL_ERROR "LIBCXX_ENABLE_ASSERTIONS has been replaced by LIBCXX_HARDENING_MODE=safe") endif() if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "serial") diff --git a/libcxx/cmake/caches/Generic-safe-mode.cmake b/libcxx/cmake/caches/Generic-safe-mode.cmake new file mode 100644 --- /dev/null +++ b/libcxx/cmake/caches/Generic-safe-mode.cmake @@ -0,0 +1 @@ +set(LIBCXX_HARDENING_MODE "safe" CACHE STRING "") diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst --- a/libcxx/docs/Hardening.rst +++ b/libcxx/docs/Hardening.rst @@ -1,30 +1,41 @@ -============= -Hardened Mode -============= +=============== +Hardening Modes +=============== .. contents:: :local: -.. _using-hardened-mode: +.. _using-hardening-modes: -Using the hardened mode -======================= +Using hardening modes +===================== The hardened mode enables a set of security-critical assertions that prevent undefined behavior caused by violating preconditions of the standard library. These assertions can be done with relatively little overhead in constant time and are intended to be used in production. -In addition to the hardened mode, libc++ also provides the debug mode which -contains all the checks from the hardened mode and additionally more expensive -checks that may affect the complexity of algorithms. The debug mode is intended -to be used for testing, not in production. +In addition to the hardened mode, libc++ also provides two other hardening +modes: +- safe mode; +- debug mode. + +The safe mode contains all the checks from the hardened mode and additionally +some checks for undefined behavior that incur relatively little overhead but +aren't security-critical. While the performance penalty is somewhat more +significant compared to the hardened mode, the safe mode is still intended to be +usable in production. + +The debug mode, in turn, contains all the checks from the safe mode and +additionally more expensive checks that may affect the complexity of algorithms. +The debug mode is intended to be used for testing, not in production. Vendors can set the default hardening mode by using the ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Setting ``LIBCXX_HARDENING_MODE`` to ``hardened`` enables the hardened mode, and -similarly setting the variable to ``debug`` enables the debug mode. The default -value is ``unchecked`` which doesn't enable any hardening. +similarly setting the variable to ``safe`` enables the safe mode, and to +``debug`` enables the debug mode. The default value is ``unchecked`` which +doesn't enable any hardening. When hardening is enabled, the compiled library is built with the corresponding mode enabled, **and** user code will be built with the same mode enabled by @@ -35,20 +46,21 @@ Furthermore, independently of any vendor-selected default, users can always control which level of hardening is enabled in their code by defining -``_LIBCPP_ENABLE_HARDENED_MODE=0|1`` (or ``_LIBCPP_ENABLE_DEBUG_MODE=0|1``) -before including any libc++ header (we recommend passing -``-D_LIBCPP_ENABLE_HARDENED_MODE=X`` or ``-D_LIBCPP_ENABLE_DEBUG_MODE=X`` to the -compiler). Note that if the compiled library was built by the vendor in the -unchecked mode, functions compiled inside the static or shared library won't -have any hardening enabled even if the user compiles with hardening enabled (the -same is true for the inverse case where the static or shared library was -compiled **with** hardening enabled but the user tries to disable it). However, -most of the code in libc++ is in the headers, so the user-selected value for -``_LIBCPP_ENABLE_HARDENED_MODE`` or ``_LIBCPP_ENABLE_DEBUG_MODE`` (if any) will -usually be respected. +``_LIBCPP_ENABLE_HARDENED_MODE=0|1`` (or ``_LIBCPP_ENABLE_SAFE_MODE=0|1``, or +``_LIBCPP_ENABLE_DEBUG_MODE=0|1``) before including any libc++ header (we +recommend passing ``-D_LIBCPP_ENABLE_HARDENED_MODE=X``, etc. to the compiler). +Note that if the compiled library was built by the vendor in the unchecked mode, +functions compiled inside the static or shared library won't have any hardening +enabled even if the user compiles with hardening enabled (the same is true for +the inverse case where the static or shared library was compiled **with** +hardening enabled but the user tries to disable it). However, most of the code +in libc++ is in the headers, so the user-selected value for +``_LIBCPP_ENABLE_HARDENED_MODE`` (or ``_LIBCPP_ENABLE_HARDENED_MODE``, or +``_LIBCPP_ENABLE_DEBUG_MODE``), if any, will usually be respected. Enabling hardening has no impact on the ABI. + Iterator bounds checking ------------------------ TODO(hardening) diff --git a/libcxx/docs/ReleaseNotes/17.rst b/libcxx/docs/ReleaseNotes/17.rst --- a/libcxx/docs/ReleaseNotes/17.rst +++ b/libcxx/docs/ReleaseNotes/17.rst @@ -111,6 +111,11 @@ enabled on a per translation unit basis using the ``-D_LIBCPP_ENABLE_HARDENED_MODE=1`` macro. See ``libcxx/docs/Hardening.rst`` for more details. +- The safe mode is now a part of hardening modes. Vendors can configure whether the safe mode is enabled by default + with the ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Users can control whether the safe mode + is enabled on a per translation unit basis using the ``-D_LIBCPP_ENABLE_SAFE_MODE=1`` macro. See + ``libcxx/docs/Hardening.rst`` for more details. + - The library now provides a debug mode which is a superset of the hardened mode, additionally enabling more expensive checks that are not suitable to be used in production. This replaces the legacy debug mode that was removed in this release. Unlike the legacy debug mode, this doesn't affect the ABI and doesn't require locking. Vendors can configure diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -215,10 +215,13 @@ disabled and must be manually enabled by the user. **_LIBCPP_ENABLE_HARDENED_MODE**: - This macro is used to enable the :ref:`hardened mode `. + This macro is used to enable the :ref:`hardened mode `. + +**_LIBCPP_ENABLE_SAFE_MODE**: + This macro is used to enable the :ref:`safe mode `. **_LIBCPP_ENABLE_DEBUG_MODE**: - This macro is used to enable the :ref:`debug mode `. + This macro is used to enable the :ref:`debug mode `. **_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS**: This macro is used to disable all visibility annotations inside libc++. diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -210,26 +210,32 @@ // TODO(hardening): remove this in LLVM 18. // This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes) -// equivalent to setting the hardened mode. +// equivalent to setting the safe mode. # ifdef _LIBCPP_ENABLE_ASSERTIONS -# warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_HARDENED_MODE instead." +# warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_SAFE_MODE instead." # if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 # error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" # endif # if _LIBCPP_ENABLE_ASSERTIONS -# define _LIBCPP_ENABLE_HARDENED_MODE 1 +# define _LIBCPP_ENABLE_SAFE_MODE 1 # endif # endif // Enables the hardened mode which consists of all checks intended to be used in production. Hardened mode prioritizes // security-critical checks that can be done with relatively little overhead in constant time. Mutually exclusive with -// `_LIBCPP_ENABLE_DEBUG_MODE`. +// `_LIBCPP_ENABLE_SAFE_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE`. // // #define _LIBCPP_ENABLE_HARDENED_MODE 1 +// Enables the safe mode which extends the hardened mode with checks that are relatively cheap and prevent common types +// of errors but are not security-critical. +// `_LIBCPP_ENABLE_HARDENED_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE`. +// +// #define _LIBCPP_ENABLE_SAFE_MODE 1 + // Enables the debug mode which contains all the checks from the hardened mode and additionally more expensive checks // that may affect the complexity of algorithms. The debug mode is intended to be used for testing, not in production. -// Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE`. +// Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE` and `_LIBCPP_ENABLE_SAFE_MODE`. // // #define _LIBCPP_ENABLE_DEBUG_MODE 1 @@ -264,6 +270,13 @@ # error "_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1." # endif +# ifndef _LIBCPP_ENABLE_SAFE_MODE +# define _LIBCPP_ENABLE_SAFE_MODE _LIBCPP_ENABLE_SAFE_MODE_DEFAULT +# endif +# if _LIBCPP_ENABLE_SAFE_MODE != 0 && _LIBCPP_ENABLE_SAFE_MODE != 1 +# error "_LIBCPP_ENABLE_SAFE_MODE must be set to 0 or 1." +# endif + # ifndef _LIBCPP_ENABLE_DEBUG_MODE # define _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT # endif @@ -271,13 +284,16 @@ # error "_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1." # endif -# if _LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE -# error "Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled." +# if (_LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_SAFE_MODE) || \ + (_LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE) || \ + (_LIBCPP_ENABLE_SAFE_MODE && _LIBCPP_ENABLE_DEBUG_MODE) +# error \ + "Only one of _LIBCPP_ENABLE_HARDENED_MODE, _LIBCPP_ENABLE_SAFE_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled." # endif +// clang-format off // Hardened mode checks. -// clang-format off # if _LIBCPP_ENABLE_HARDENED_MODE // Enabled checks. @@ -291,6 +307,20 @@ # define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) # define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) +// Safe mode checks. + +# elif _LIBCPP_ENABLE_SAFE_MODE + +// Enabled checks. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) +// TODO(hardening): don't enable uncategorized assertions in the safe mode. +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) +// Disabled checks. +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) + // Debug mode checks. # elif _LIBCPP_ENABLE_DEBUG_MODE diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -36,6 +36,7 @@ // Hardening. #cmakedefine01 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT +#cmakedefine01 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT #cmakedefine01 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT // __USE_MINGW_ANSI_STDIO gets redefined on MinGW diff --git a/libcxx/test/libcxx/algorithms/alg.sorting/assert.min.max.pass.cpp b/libcxx/test/libcxx/algorithms/alg.sorting/assert.min.max.pass.cpp --- a/libcxx/test/libcxx/algorithms/alg.sorting/assert.min.max.pass.cpp +++ b/libcxx/test/libcxx/algorithms/alg.sorting/assert.min.max.pass.cpp @@ -10,7 +10,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp @@ -8,7 +8,7 @@ // This test ensures that we can disable the debug mode on a per-TU basis regardless of how the library was built. -// UNSUPPORTED: libcpp-hardening-mode=hardened +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=debug // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_DEBUG_MODE=0 #include diff --git a/libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp @@ -8,8 +8,8 @@ // This test ensures that we can enable the debug mode on a per-TU basis regardless of how the library was built. -// Hardened mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=hardened +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=debug // `check_assertion.h` is only available starting from C++11 and requires Unix headers. // UNSUPPORTED: c++03, !has-unix-headers // The ability to set a custom abort message is required to compare the assertion message. diff --git a/libcxx/test/libcxx/assertions/modes/debug_mode_not_1_or_0.verify.cpp b/libcxx/test/libcxx/assertions/modes/debug_mode_not_1_or_0.verify.cpp --- a/libcxx/test/libcxx/assertions/modes/debug_mode_not_1_or_0.verify.cpp +++ b/libcxx/test/libcxx/assertions/modes/debug_mode_not_1_or_0.verify.cpp @@ -8,8 +8,8 @@ // This test verifies that setting the debug mode to a value other than `0` or `1` triggers a compile-time error. -// Hardened mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=hardened +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=debug // Modules build produces a different error ("Could not build module 'std'"). // UNSUPPORTED: modules-build // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_DEBUG_MODE=2 diff --git a/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_hardened_mode.pass.cpp b/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_hardened_mode.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_hardened_mode.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_hardened_mode.pass.cpp @@ -7,14 +7,14 @@ //===----------------------------------------------------------------------===// // TODO(hardening): remove in LLVM 18. -// This test ensures that enabling assertions now enables the hardened mode. +// This test ensures that enabling assertions now enables the safe mode. +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=safe // `check_assertion.h` is only available starting from C++11 and requires Unix headers. // UNSUPPORTED: c++03, !has-unix-headers // The ability to set a custom abort message is required to compare the assertion message. // XFAIL: availability-verbose_abort-missing -// Debug mode is mutually exclusive with hardened mode. -// UNSUPPORTED: libcpp-hardening-mode=debug // Ignore the warning about `_LIBCPP_ENABLE_ASSERTIONS` being deprecated. // ADDITIONAL_COMPILE_FLAGS: -Wno-error -D_LIBCPP_ENABLE_ASSERTIONS=1 @@ -22,7 +22,7 @@ #include "check_assertion.h" int main(int, char**) { - static_assert(_LIBCPP_ENABLE_HARDENED_MODE == 1, "Hardened mode should be implicitly enabled"); + static_assert(_LIBCPP_ENABLE_SAFE_MODE == 1, "Safe mode should be implicitly enabled"); _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire"); TEST_LIBCPP_ASSERT_FAILURE([] { diff --git a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp b/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp +++ b/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp @@ -8,10 +8,11 @@ // This test verifies that `_LIBCPP_ENABLE_HARDENED_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE` are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked // Modules build produces a different error ("Could not build module 'std'"). // UNSUPPORTED: modules-build // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1 #include -// expected-error@*:* {{Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled.}} +// expected-error@*:* {{Only one of _LIBCPP_ENABLE_HARDENED_MODE, _LIBCPP_ENABLE_SAFE_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled.}} diff --git a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp b/libcxx/test/libcxx/assertions/modes/hardened_and_safe_mutually_exclusive.verify.cpp copy from libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp copy to libcxx/test/libcxx/assertions/modes/hardened_and_safe_mutually_exclusive.verify.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp +++ b/libcxx/test/libcxx/assertions/modes/hardened_and_safe_mutually_exclusive.verify.cpp @@ -8,10 +8,11 @@ // This test verifies that `_LIBCPP_ENABLE_HARDENED_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE` are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked // Modules build produces a different error ("Could not build module 'std'"). // UNSUPPORTED: modules-build // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1 #include -// expected-error@*:* {{Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled.}} +// expected-error@*:* {{Only one of _LIBCPP_ENABLE_HARDENED_MODE, _LIBCPP_ENABLE_SAFE_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled.}} diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_disabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/hardened_mode_disabled_in_tu.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_mode_disabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/hardened_mode_disabled_in_tu.pass.cpp @@ -8,7 +8,8 @@ // This test ensures that we can disable the hardened mode on a per-TU basis regardless of how the library was built. -// UNSUPPORTED: libcpp-hardening-mode=debug +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=hardened // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=0 #include diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp @@ -8,8 +8,8 @@ // This test ensures that we can enable the hardened mode on a per-TU basis regardless of how the library was built. -// Debug mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=debug +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=hardened // `check_assertion.h` is only available starting from C++11. // UNSUPPORTED: c++03 // `check_assertion.h` requires Unix headers. diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp b/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp +++ b/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp @@ -8,8 +8,8 @@ // This test verifies that setting the hardened mode to a value other than `0` or `1` triggers a compile-time error. -// Debug mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=debug +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=hardened // Modules build produces a different error ("Could not build module 'std'"). // UNSUPPORTED: modules-build // ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=2 diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/safe.pass.cpp copy from libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp copy to libcxx/test/libcxx/assertions/modes/safe.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/safe.pass.cpp @@ -6,17 +6,15 @@ // //===----------------------------------------------------------------------===// -// This test ensures that we can enable the hardened mode on a per-TU basis regardless of how the library was built. +// This test ensures that assertions trigger without the user having to do anything when the safe mode has been +// enabled by default. -// Debug mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=debug +// REQUIRES: libcpp-hardening-mode=safe // `check_assertion.h` is only available starting from C++11. // UNSUPPORTED: c++03 // `check_assertion.h` requires Unix headers. // REQUIRES: has-unix-headers -// The ability to set a custom abort message is required to compare the assertion message. // XFAIL: availability-verbose_abort-missing -// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 #include #include "check_assertion.h" diff --git a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp b/libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp copy from libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp copy to libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp +++ b/libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp @@ -6,12 +6,13 @@ // //===----------------------------------------------------------------------===// -// This test verifies that `_LIBCPP_ENABLE_HARDENED_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE` are mutually exclusive. +// This test verifies that `_LIBCPP_ENABLE_SAFE_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE` are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked // Modules build produces a different error ("Could not build module 'std'"). // UNSUPPORTED: modules-build -// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1 +// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1 #include -// expected-error@*:* {{Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled.}} +// expected-error@*:* {{Only one of _LIBCPP_ENABLE_HARDENED_MODE, _LIBCPP_ENABLE_SAFE_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled.}} diff --git a/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/safe_mode_disabled_in_tu.pass.cpp copy from libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp copy to libcxx/test/libcxx/assertions/modes/safe_mode_disabled_in_tu.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/safe_mode_disabled_in_tu.pass.cpp @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -// This test ensures that we can disable the debug mode on a per-TU basis regardless of how the library was built. +// This test ensures that we can disable the safe mode on a per-TU basis regardless of how the library was built. -// UNSUPPORTED: libcpp-hardening-mode=hardened -// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_DEBUG_MODE=0 +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=safe +// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=0 #include diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/safe_mode_enabled_in_tu.pass.cpp copy from libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp copy to libcxx/test/libcxx/assertions/modes/safe_mode_enabled_in_tu.pass.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp +++ b/libcxx/test/libcxx/assertions/modes/safe_mode_enabled_in_tu.pass.cpp @@ -6,17 +6,17 @@ // //===----------------------------------------------------------------------===// -// This test ensures that we can enable the hardened mode on a per-TU basis regardless of how the library was built. +// This test ensures that we can enable the safe mode on a per-TU basis regardless of how the library was built. -// Debug mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=debug +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=safe // `check_assertion.h` is only available starting from C++11. // UNSUPPORTED: c++03 // `check_assertion.h` requires Unix headers. // REQUIRES: has-unix-headers // The ability to set a custom abort message is required to compare the assertion message. // XFAIL: availability-verbose_abort-missing -// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 +// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=1 #include #include "check_assertion.h" diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp b/libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp copy from libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp copy to libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp --- a/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp +++ b/libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -// This test verifies that setting the hardened mode to a value other than `0` or `1` triggers a compile-time error. +// This test verifies that setting the safe mode to a value other than `0` or `1` triggers a compile-time error. -// Debug mode would additionally trigger the error that hardened and debug modes are mutually exclusive. -// UNSUPPORTED: libcpp-hardening-mode=debug +// Other hardening modes would additionally trigger the error that they are mutually exclusive. +// REQUIRES: libcpp-hardening-mode=unchecked || libcpp-hardening-mode=safe // Modules build produces a different error ("Could not build module 'std'"). // UNSUPPORTED: modules-build -// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=2 +// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=2 #include -// expected-error@*:* {{_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1.}} +// expected-error@*:* {{_LIBCPP_ENABLE_SAFE_MODE must be set to 0 or 1.}} diff --git a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp @@ -12,7 +12,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp @@ -17,7 +17,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp @@ -17,7 +17,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp @@ -17,7 +17,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp @@ -16,7 +16,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp @@ -17,7 +17,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp --- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp --- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp --- a/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp @@ -6,7 +6,7 @@ //===----------------------------------------------------------------------===// // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp b/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp --- a/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp +++ b/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp @@ -14,7 +14,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS diff --git a/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp b/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp --- a/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp +++ b/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp @@ -14,7 +14,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS diff --git a/libcxx/test/libcxx/iterators/assert.advance.pass.cpp b/libcxx/test/libcxx/iterators/assert.advance.pass.cpp --- a/libcxx/test/libcxx/iterators/assert.advance.pass.cpp +++ b/libcxx/test/libcxx/iterators/assert.advance.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/iterators/assert.next.pass.cpp b/libcxx/test/libcxx/iterators/assert.next.pass.cpp --- a/libcxx/test/libcxx/iterators/assert.next.pass.cpp +++ b/libcxx/test/libcxx/iterators/assert.next.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/iterators/assert.prev.pass.cpp b/libcxx/test/libcxx/iterators/assert.prev.pass.cpp --- a/libcxx/test/libcxx/iterators/assert.prev.pass.cpp +++ b/libcxx/test/libcxx/iterators/assert.prev.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp --- a/libcxx/test/libcxx/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp @@ -13,7 +13,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17 // UNSUPPORTED: no-exceptions -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp --- a/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp --- a/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp b/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp --- a/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // REQUIRES: has-unix-headers // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp b/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp --- a/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // REQUIRES: has-unix-headers // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/strings/string.view/assert.ctor.length.pass.cpp b/libcxx/test/libcxx/strings/string.view/assert.ctor.length.pass.cpp --- a/libcxx/test/libcxx/strings/string.view/assert.ctor.length.pass.cpp +++ b/libcxx/test/libcxx/strings/string.view/assert.ctor.length.pass.cpp @@ -9,7 +9,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // Construct a string_view from an invalid length diff --git a/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp b/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp --- a/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp +++ b/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // Construct a string_view from a null pointer diff --git a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp --- a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp +++ b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, no-threads -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp --- a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp +++ b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, no-threads -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp b/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp --- a/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-threads // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/thread/thread.barrier/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.barrier/assert.ctor.pass.cpp --- a/libcxx/test/libcxx/thread/thread.barrier/assert.ctor.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.barrier/assert.ctor.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-threads // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp --- a/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp @@ -17,7 +17,7 @@ // Make sure that calling arrive_and_wait with a negative value triggers an assertion. // REQUIRES: has-unix-headers -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp --- a/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp @@ -18,7 +18,7 @@ // higher than the internal counter triggers an assertion. // REQUIRES: has-unix-headers -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp --- a/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp @@ -17,7 +17,7 @@ // Make sure that calling latch with a negative value triggers an assertion // REQUIRES: has-unix-headers -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing #include diff --git a/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp --- a/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-threads // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/thread/thread.semaphore/assert.release.pass.cpp b/libcxx/test/libcxx/thread/thread.semaphore/assert.release.pass.cpp --- a/libcxx/test/libcxx/thread/thread.semaphore/assert.release.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.semaphore/assert.release.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: no-threads // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp b/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp --- a/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp +++ b/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // ADDITIONAL_COMPILE_FLAGS: -fno-exceptions diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.pop_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.pop_heap.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.pop_heap.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.pop_heap.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.ranges_pop_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.ranges_pop_heap.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.ranges_pop_heap.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/assert.ranges_pop_heap.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.clamp/assert.ranges_clamp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.clamp/assert.ranges_clamp.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.clamp/assert.ranges_clamp.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.clamp/assert.ranges_clamp.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // diff --git a/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.pass.cpp b/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.pass.cpp --- a/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.pass.cpp @@ -8,7 +8,7 @@ // REQUIRES: has-unix-headers // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: !libcpp-hardening-mode=safe && !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // Make sure that reaching std::unreachable() with assertions enabled triggers an assertion. diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -495,6 +495,24 @@ limit: 2 timeout_in_minutes: 120 + - label: "Safe mode" + command: "libcxx/utils/ci/run-buildbot generic-safe-mode" + artifact_paths: + - "**/test-results.xml" + - "**/*.abilist" + env: + CC: "clang-${LLVM_HEAD_VERSION}" + CXX: "clang++-${LLVM_HEAD_VERSION}" + ENABLE_CLANG_TIDY: "On" + agents: + queue: "libcxx-builders" + os: "linux" + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + timeout_in_minutes: 120 + - label: "Debug mode" command: "libcxx/utils/ci/run-buildbot generic-debug-mode" artifact_paths: diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -399,6 +399,12 @@ check-runtimes check-abi-list ;; +generic-safe-mode) + clean + generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-safe-mode.cmake" + check-runtimes + check-abi-list +;; generic-debug-mode) clean generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-debug-mode.cmake" diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -290,15 +290,16 @@ ), Parameter( name="hardening_mode", - choices=["unchecked", "hardened", "debug"], + choices=["unchecked", "hardened", "safe", "debug"], type=str, default="unchecked", - help="Whether to enable the hardened mode or the debug mode when compiling the test suite. This is only " + help="Whether to enable one of the hardening modes when compiling the test suite. This is only " "meaningful when running the tests against libc++.", actions=lambda hardening_mode: filter( None, [ AddCompileFlag("-D_LIBCPP_ENABLE_HARDENED_MODE=1") if hardening_mode == "hardened" else None, + AddCompileFlag("-D_LIBCPP_ENABLE_SAFE_MODE=1") if hardening_mode == "safe" else None, AddCompileFlag("-D_LIBCPP_ENABLE_DEBUG_MODE=1") if hardening_mode == "debug" else None, AddFeature("libcpp-hardening-mode={}".format(hardening_mode)), ],