[libcxx-commits] [libcxx] [libc++][hardening] Rework macros for enabling the hardening mode. (PR #70575)
Konstantin Varlamov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Oct 28 14:43:35 PDT 2023
https://github.com/var-const created https://github.com/llvm/llvm-project/pull/70575
1. Instead of using individual "boolean" macros, have an "enum" macro
`_LIBCPP_HARDENING_MODE`. This avoids issues with macros being
mutually exclusive and makes overriding the hardening mode within a TU
more straightforward.
2. Rename the safe mode to debug-lite.
This brings the code in line with the RFC:
https://discourse.llvm.org/t/rfc-hardening-in-libc/73925
>From 26bbe1cf58df8abfc0eb24ce7e6492d47fe515c2 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconsteq at gmail.com>
Date: Fri, 27 Oct 2023 14:16:34 -0700
Subject: [PATCH] [libc++][hardening] Rework macros for enabling the hardening
mode.
1. Instead of using individual "boolean" macros, have an "enum" macro
`_LIBCPP_HARDENING_MODE`. This avoids issues with macros being
mutually exclusive and makes overriding the hardening mode within a TU
more straightforward.
2. Rename the safe mode to debug-lite.
This brings the code in line with the RFC:
https://discourse.llvm.org/t/rfc-hardening-in-libc/73925
---
libcxx/CMakeLists.txt | 28 +++----
libcxx/docs/Hardening.rst | 39 +++++----
libcxx/docs/ReleaseNotes/18.rst | 23 +++--
libcxx/docs/UsingLibcxx.rst | 10 +--
libcxx/include/__algorithm/comp_ref_type.h | 2 +-
.../__algorithm/three_way_comp_ref_type.h | 2 +-
libcxx/include/__config | 83 +++++++++----------
libcxx/include/__config_site.in | 4 +-
.../make.heap/complexity.pass.cpp | 2 +-
.../{safe.pass.cpp => debug_lite.pass.cpp} | 4 +-
.../modes/debug_mode_disabled_in_tu.pass.cpp | 23 -----
.../modes/debug_mode_not_1_or_0.verify.cpp | 19 -----
...ling_assertions_enables_safe_mode.pass.cpp | 9 +-
...ed_and_debug_mutually_exclusive.verify.cpp | 18 ----
...ned_and_safe_mutually_exclusive.verify.cpp | 18 ----
.../hardened_mode_disabled_in_tu.pass.cpp | 23 -----
...hardening_mode_incorrect_value.verify.cpp} | 9 +-
.../override_with_debug_lite_mode.pass.cpp | 30 +++++++
....cpp => override_with_debug_mode.pass.cpp} | 18 ++--
...p => override_with_hardened_mode.pass.cpp} | 11 ++-
... => override_with_unchecked_mode.pass.cpp} | 10 +--
...fe_and_debug_mutually_exclusive.verify.cpp | 18 ----
.../modes/safe_mode_disabled_in_tu.pass.cpp | 23 -----
.../modes/safe_mode_not_1_or_0.verify.cpp | 19 -----
.../libcxx/odr_signature.hardening.sh.cpp | 16 ++--
.../sort.heap/complexity.pass.cpp | 2 +-
.../sort.heap/ranges_sort_heap.pass.cpp | 2 +-
.../alg.merge/inplace_merge_comp.pass.cpp | 2 +-
...ographical_compare_three_way_comp.pass.cpp | 2 +-
libcxx/test/support/container_debug_tests.h | 2 +-
libcxx/utils/ci/buildkite-pipeline.yml | 4 +-
libcxx/utils/libcxx/test/params.py | 9 +-
.../gn/secondary/libcxx/include/BUILD.gn | 4 +-
33 files changed, 170 insertions(+), 318 deletions(-)
rename libcxx/test/libcxx/assertions/modes/{safe.pass.cpp => debug_lite.pass.cpp} (90%)
delete mode 100644 libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp
delete mode 100644 libcxx/test/libcxx/assertions/modes/debug_mode_not_1_or_0.verify.cpp
delete mode 100644 libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp
delete mode 100644 libcxx/test/libcxx/assertions/modes/hardened_and_safe_mutually_exclusive.verify.cpp
delete mode 100644 libcxx/test/libcxx/assertions/modes/hardened_mode_disabled_in_tu.pass.cpp
rename libcxx/test/libcxx/assertions/modes/{hardened_mode_not_1_or_0.verify.cpp => hardening_mode_incorrect_value.verify.cpp} (53%)
create mode 100644 libcxx/test/libcxx/assertions/modes/override_with_debug_lite_mode.pass.cpp
rename libcxx/test/libcxx/assertions/modes/{debug_mode_enabled_in_tu.pass.cpp => override_with_debug_mode.pass.cpp} (52%)
rename libcxx/test/libcxx/assertions/modes/{safe_mode_enabled_in_tu.pass.cpp => override_with_hardened_mode.pass.cpp} (66%)
rename libcxx/test/libcxx/assertions/modes/{hardened_mode_enabled_in_tu.pass.cpp => override_with_unchecked_mode.pass.cpp} (66%)
delete mode 100644 libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp
delete mode 100644 libcxx/test/libcxx/assertions/modes/safe_mode_disabled_in_tu.pass.cpp
delete mode 100644 libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index d03421afde1e755..b9f7ab8466aa806 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -59,7 +59,7 @@ option(LIBCXX_ENABLE_FILESYSTEM
available on the platform. This includes things like most parts of <filesystem> and
others like <fstream>" ON)
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
-set(LIBCXX_SUPPORTED_HARDENING_MODES unchecked hardened safe debug)
+set(LIBCXX_SUPPORTED_HARDENING_MODES unchecked hardened debug_lite 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
@@ -752,24 +752,16 @@ config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_N
# TODO(LLVM 19): Produce a deprecation warning.
if (LIBCXX_ENABLE_ASSERTIONS)
- set(LIBCXX_HARDENING_MODE "safe")
-endif()
-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)
+ set(LIBCXX_HARDENING_MODE "debug_lite")
+endif()
+if (LIBCXX_HARDENING_MODE STREQUAL "unchecked")
+ config_define(2 _LIBCPP_HARDENING_MODE_DEFAULT)
+elseif (LIBCXX_HARDENING_MODE STREQUAL "hardened")
+ config_define(4 _LIBCPP_HARDENING_MODE_DEFAULT)
+elseif (LIBCXX_HARDENING_MODE STREQUAL "debug_lite")
+ config_define(16 _LIBCPP_HARDENING_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)
+ config_define(8 _LIBCPP_HARDENING_MODE_DEFAULT)
endif()
if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "serial")
diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index ec115d3d6012bfe..738fd3235d12e22 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -17,25 +17,25 @@ and are intended to be used in production.
In addition to the hardened mode, libc++ also provides two other hardening
modes:
-- safe mode;
+- debug-lite 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-lite 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 debug-lite mode is still
+intended to be usable in production.
-The debug mode, in turn, contains all the checks from the safe mode and
+The debug mode, in turn, contains all the checks from the debug-lite 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 ``safe`` enables the safe mode, and to
-``debug`` enables the debug mode. The default value is ``unchecked`` which
-doesn't enable any hardening.
+similarly setting the variable to ``debug_lite`` enables the debug-lite 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
@@ -45,17 +45,26 @@ user code will be to have assertions disabled. As a user, you can consult your
vendor to know which level of hardening is enabled by default.
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_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).
+control which level of hardening is enabled in their code by defining the macro
+``_LIBCPP_HARDENING_MODE`` before including any libc++ headers (preferably by
+passing ``-D_LIBCPP_HARDENING_MODE=X`` to the compiler). The macro can be
+set to one of the following possible values:
+
+- ``_LIBCPP_HARDENING_MODE_UNCHECKED``;
+- ``_LIBCPP_HARDENING_MODE_HARDENED``;
+- ``_LIBCPP_HARDENING_MODE_DEBUG_LITE``;
+- ``_LIBCPP_HARDENING_MODE_DEBUG``.
+
+The exact numeric values of these macros are unspecified and you should not rely
+on them (e.g. expect the values to be sorted in any way).
+
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|SAFE|DEBUG_MODE``, if any, will usually be respected.
+``_LIBCPP_HARDENING_MODE``, if any, will usually be respected.
Enabling hardening has no impact on the ABI.
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index ac78563aa73848f..d0f28a53dbee6ea 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -58,16 +58,23 @@ Improvements and New Features
- The library now provides a hardened mode under which common cases of library undefined behavior will be turned into
a reliable program termination. Vendors can configure whether the hardened mode is enabled by default with the
``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Users can control whether the hardened mode is
- enabled on a per translation unit basis using the ``-D_LIBCPP_ENABLE_HARDENED_MODE=1`` macro. See
+ enabled on a per translation unit basis using the ``_LIBCPP_HARDENING_MODE`` macro. See
:ref:`the hardening documentation <using-hardening-modes>` for more details.
-- The library now provides a debug mode which is a superset of the safe mode, additionally enabling more expensive
+- The library now provides a debug-lite mode which is a superset of the hardened mode, additionally enabling checks that
+ catch common logic errors that aren't necessarily security-critical. This mode is largely a replacement for the safe
+ release. Unlike the legacy debug mode, this doesn't affect the ABI and doesn't require locking. Vendors can configure
+ whether the debug-lite mode is enabled by default with the ``LIBCXX_HARDENING_MODE`` variable at CMake configuration
+ time. ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Users can control whether the hardened mode is
+ enabled on a per translation unit basis using the ``_LIBCPP_HARDENING_MODE`` macro. See
+ :ref:`the hardening documentation <using-hardening-modes>` for more details.
+
+- The library now provides a debug mode which is a superset of the debug-lite 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
whether the debug mode is enabled by default with the ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time.
- Users can control whether the debug mode is enabled on a per translation unit basis using the
- ``-D_LIBCPP_ENABLE_DEBUG_MODE=1`` macro. See :ref:`the hardening documentation <using-hardening-modes>` for more
- details.
+ Users can control whether the debug mode is enabled on a per translation unit basis using the ``_LIBCPP_HARDENING_MODE``
+ macro. See :ref:`the hardening documentation <using-hardening-modes>` for more details.
Deprecations and Removals
-------------------------
@@ -82,7 +89,7 @@ LLVM 18
~~~~~~~
- The ``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro will not be honored anymore in LLVM 18.
- Please see the updated documentation about the safe libc++ mode and in particular the ``_LIBCPP_VERBOSE_ABORT``
+ Please see the updated documentation about the hardened libc++ mode and in particular the ``_LIBCPP_VERBOSE_ABORT``
macro for details.
- The headers ``<experimental/deque>``, ``<experimental/forward_list>``, ``<experimental/list>``,
@@ -95,8 +102,8 @@ LLVM 19
~~~~~~~
- The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable that was used to enable the safe mode will be deprecated and setting
- it will trigger an error; use the ``LIBCXX_HARDENING_MODE`` variable with the value ``safe`` instead. Similarly, the
- ``_LIBCPP_ENABLE_ASSERTIONS`` macro will be deprecated (setting it to ``1`` still enables the safe mode the LLVM 19
+ it will trigger an error; use the ``LIBCXX_HARDENING_MODE`` variable with the value ``debug_lite`` instead. Similarly, the
+ ``_LIBCPP_ENABLE_ASSERTIONS`` macro will be deprecated (setting it to ``1`` still enables the debug-lite mode the LLVM 19
release while also issuing a deprecation warning). See :ref:`the hardening documentation <using-hardening-modes>` for
more details.
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 52c76f3b10548fb..24d6a7b95f5b2e4 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -223,14 +223,8 @@ safety annotations.
``std::mutex`` and ``std::lock_guard``. By default, these annotations are
disabled and must be manually enabled by the user.
-**_LIBCPP_ENABLE_HARDENED_MODE**:
- This macro is used to enable the :ref:`hardened mode <using-hardening-modes>`.
-
-**_LIBCPP_ENABLE_SAFE_MODE**:
- This macro is used to enable the :ref:`safe mode <using-hardening-modes>`.
-
-**_LIBCPP_ENABLE_DEBUG_MODE**:
- This macro is used to enable the :ref:`debug mode <using-hardening-modes>`.
+**_LIBCPP_HARDENING_MODE**:
+ This macro is used to choose the :ref:`hardening mode <using-hardening-modes>`.
**_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS**:
This macro is used to disable all visibility annotations inside libc++.
diff --git a/libcxx/include/__algorithm/comp_ref_type.h b/libcxx/include/__algorithm/comp_ref_type.h
index d16bd0f5310003f..2aeb55f550b53c2 100644
--- a/libcxx/include/__algorithm/comp_ref_type.h
+++ b/libcxx/include/__algorithm/comp_ref_type.h
@@ -65,7 +65,7 @@ struct __debug_less
// Pass the comparator by lvalue reference. Or in debug mode, using a
// debugging wrapper that stores a reference.
-#if _LIBCPP_ENABLE_DEBUG_MODE
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
template <class _Comp>
using __comp_ref_type = __debug_less<_Comp>;
#else
diff --git a/libcxx/include/__algorithm/three_way_comp_ref_type.h b/libcxx/include/__algorithm/three_way_comp_ref_type.h
index 7731c0fd791d809..8fd15c5d66f2fc9 100644
--- a/libcxx/include/__algorithm/three_way_comp_ref_type.h
+++ b/libcxx/include/__algorithm/three_way_comp_ref_type.h
@@ -58,7 +58,7 @@ struct __debug_three_way_comp {
// Pass the comparator by lvalue reference. Or in debug mode, using a
// debugging wrapper that stores a reference.
-# if _LIBCPP_ENABLE_DEBUG_MODE
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
template <class _Comp>
using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>;
# else
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 4bf171f998c6f05..d5aa49f72934640 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -217,33 +217,36 @@
// TODO(hardening): deprecate this in LLVM 19.
// This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes)
-// equivalent to setting the safe mode.
+// equivalent to setting the debug-lite mode.
# ifdef _LIBCPP_ENABLE_ASSERTIONS
# 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_SAFE_MODE 1
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEBUG_LITE
# endif
# endif
+// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values:
+// - `_LIBCPP_HARDENING_MODE_UNCHECKED`;
+// - `_LIBCPP_HARDENING_MODE_HARDENED`;
+// - `_LIBCPP_HARDENING_MODE_DEBUG_LITE`;
+// - `_LIBCPP_HARDENING_MODE_DEBUG`.
+
// 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_SAFE_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE`.
+// security-critical checks that can be done with relatively little overhead in constant time.
//
-// #define _LIBCPP_ENABLE_HARDENED_MODE 1
+// #define _LIBCPP_HARDENING_MODE_HARDENED 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. Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE` and
-// `_LIBCPP_ENABLE_DEBUG_MODE`.
+// Enables the debug-lite mode which extends the hardened mode with checks that are relatively cheap and prevent common
+// types of errors but are not security-critical.
//
-// #define _LIBCPP_ENABLE_SAFE_MODE 1
+// #define _LIBCPP_HARDENING_MODE_DEBUG_LITE 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` and `_LIBCPP_ENABLE_SAFE_MODE`.
//
-// #define _LIBCPP_ENABLE_DEBUG_MODE 1
+// #define _LIBCPP_HARDENING_MODE_DEBUG 1
// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These
// macros are only for internal use -- users should only pick one of the high-level hardening modes described above.
@@ -269,38 +272,32 @@
//
// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet.
-# ifndef _LIBCPP_ENABLE_HARDENED_MODE
-# define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT
-# endif
-# if _LIBCPP_ENABLE_HARDENED_MODE != 0 && _LIBCPP_ENABLE_HARDENED_MODE != 1
-# 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
+// clang-format off
+# define _LIBCPP_HARDENING_MODE_UNCHECKED (1 << 1)
+# define _LIBCPP_HARDENING_MODE_HARDENED (1 << 2)
+# define _LIBCPP_HARDENING_MODE_DEBUG_LITE (1 << 4) // Deliberately not ordered.
+# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3)
+// clang-format on
-# ifndef _LIBCPP_ENABLE_DEBUG_MODE
-# define _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT
-# endif
-# if _LIBCPP_ENABLE_DEBUG_MODE != 0 && _LIBCPP_ENABLE_DEBUG_MODE != 1
-# error "_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1."
+# ifndef _LIBCPP_HARDENING_MODE
+# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT
# endif
-# 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."
+# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_UNCHECKED && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_HARDENED && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG_LITE && \
+ _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
+# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \
+_LIBCPP_HARDENING_MODE_UNCHECKED, \
+_LIBCPP_HARDENING_MODE_HARDENED, \
+_LIBCPP_HARDENING_MODE_DEBUG_LITE, \
+_LIBCPP_HARDENING_MODE_DEBUG
# endif
// clang-format off
// Hardened mode checks.
-# if _LIBCPP_ENABLE_HARDENED_MODE
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_HARDENED
// Enabled checks.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
@@ -313,9 +310,9 @@
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
-// Safe mode checks.
+// Debug-lite mode checks.
-# elif _LIBCPP_ENABLE_SAFE_MODE
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG_LITE
// Enabled checks.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
@@ -328,7 +325,7 @@
// Debug mode checks.
-# elif _LIBCPP_ENABLE_DEBUG_MODE
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
// All checks enabled.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
@@ -350,7 +347,7 @@
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
-# endif // _LIBCPP_ENABLE_HARDENED_MODE
+# endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_HARDENED
// clang-format on
// } HARDENING
@@ -730,11 +727,11 @@ typedef __char32_t char32_t;
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
# endif
-# if _LIBCPP_ENABLE_HARDENED_MODE
+# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_HARDENED
# define _LIBCPP_HARDENING_SIG h
-# elif _LIBCPP_ENABLE_SAFE_MODE
-# define _LIBCPP_HARDENING_SIG s
-# elif _LIBCPP_ENABLE_DEBUG_MODE
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG_LITE
+# define _LIBCPP_HARDENING_SIG s // "safe"
+# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
# define _LIBCPP_HARDENING_SIG d
# else
# define _LIBCPP_HARDENING_SIG u // for unchecked
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index c85cbcd02c441b9..6cade6f10d8acc1 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -36,9 +36,7 @@
#cmakedefine _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH
// Hardening.
-#cmakedefine01 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT
-#cmakedefine01 _LIBCPP_ENABLE_SAFE_MODE_DEFAULT
-#cmakedefine01 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT
+#cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@
// __USE_MINGW_ANSI_STDIO gets redefined on MinGW
#ifdef __clang__
diff --git a/libcxx/test/libcxx/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp b/libcxx/test/libcxx/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp
index a8032d032a4671b..81ff96c7295fa1e 100644
--- a/libcxx/test/libcxx/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp
@@ -64,7 +64,7 @@ int main(int, char**)
std::make_heap(v.begin(), v.end());
assert(stats.copied == 0);
assert(stats.moved == 153'486);
-#if !_LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
assert(stats.compared == 188'285);
#endif
diff --git a/libcxx/test/libcxx/assertions/modes/safe.pass.cpp b/libcxx/test/libcxx/assertions/modes/debug_lite.pass.cpp
similarity index 90%
rename from libcxx/test/libcxx/assertions/modes/safe.pass.cpp
rename to libcxx/test/libcxx/assertions/modes/debug_lite.pass.cpp
index 7174fd3078d63b9..ad3f7ca2a150905 100644
--- a/libcxx/test/libcxx/assertions/modes/safe.pass.cpp
+++ b/libcxx/test/libcxx/assertions/modes/debug_lite.pass.cpp
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-// This test ensures that assertions trigger without the user having to do anything when the safe mode has been
+// This test ensures that assertions trigger without the user having to do anything when the debug-lite mode has been
// enabled by default.
-// REQUIRES: libcpp-hardening-mode=safe
+// REQUIRES: libcpp-hardening-mode=debug_lite
// `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/debug_mode_disabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp
deleted file mode 100644
index fc8158ca0d696ca..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/debug_mode_disabled_in_tu.pass.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// This test ensures that we can disable the debug mode on a per-TU basis.
-
-// Other hardening modes would still make the assertions fire (disabling the debug mode doesn't disable e.g. the
-// hardened mode).
-// REQUIRES: libcpp-hardening-mode=debug
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_DEBUG_MODE=0
-
-#include <cassert>
-
-int main(int, char**) {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
-
- return 0;
-}
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
deleted file mode 100644
index b3b249fc0e15cbb..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/debug_mode_not_1_or_0.verify.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// This test verifies that setting the debug mode to a value other than `0` or `1` triggers a compile-time error.
-
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
-// Modules build produces a different error ("Could not build module 'std'").
-// UNSUPPORTED: clang-modules-build
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_DEBUG_MODE=2
-
-#include <cassert>
-
-// expected-error@*:* {{_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1.}}
diff --git a/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp b/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp
index 61cf26bd2ae142d..9f5458519f9faed 100644
--- a/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp
+++ b/libcxx/test/libcxx/assertions/modes/enabling_assertions_enables_safe_mode.pass.cpp
@@ -7,21 +7,20 @@
//===----------------------------------------------------------------------===//
// TODO(hardening): remove in LLVM 20.
-// This test ensures that enabling assertions now enables the safe mode.
+// This test ensures that enabling assertions now enables the debug-lite mode.
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
// `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
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=1
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
- static_assert(_LIBCPP_ENABLE_SAFE_MODE == 1, "Safe mode should be implicitly enabled");
+ static_assert(_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG_LITE,
+ "Debug-lite 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
deleted file mode 100644
index d7b2610687578ff..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/hardened_and_debug_mutually_exclusive.verify.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// 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: clang-modules-build
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1
-
-#include <cassert>
-
-// 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_safe_mutually_exclusive.verify.cpp b/libcxx/test/libcxx/assertions/modes/hardened_and_safe_mutually_exclusive.verify.cpp
deleted file mode 100644
index 464f9b86de236c4..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/hardened_and_safe_mutually_exclusive.verify.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// This test verifies that `_LIBCPP_ENABLE_HARDENED_MODE` and `_LIBCPP_ENABLE_SAFE_MODE` are mutually exclusive.
-
-// REQUIRES: libcpp-hardening-mode=unchecked
-// Modules build produces a different error ("Could not build module 'std'").
-// UNSUPPORTED: clang-modules-build
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=1 -D_LIBCPP_ENABLE_SAFE_MODE=1
-
-#include <cassert>
-
-// 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
deleted file mode 100644
index 161275977166a58..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/hardened_mode_disabled_in_tu.pass.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// This test ensures that we can disable the hardened mode on a per-TU basis.
-
-// Other hardening modes would still make the assertions fire (disabling the hardened mode doesn't disable e.g. the
-// debug mode).
-// REQUIRES: libcpp-hardening-mode=hardened
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=0
-
-#include <cassert>
-
-int main(int, char**) {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
-
- return 0;
-}
diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp b/libcxx/test/libcxx/assertions/modes/hardening_mode_incorrect_value.verify.cpp
similarity index 53%
rename from libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp
rename to libcxx/test/libcxx/assertions/modes/hardening_mode_incorrect_value.verify.cpp
index f11148d63a95348..c0723e3f13c5b2e 100644
--- a/libcxx/test/libcxx/assertions/modes/hardened_mode_not_1_or_0.verify.cpp
+++ b/libcxx/test/libcxx/assertions/modes/hardening_mode_incorrect_value.verify.cpp
@@ -6,14 +6,13 @@
//
//===----------------------------------------------------------------------===//
-// 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 hardening mode to a value that's not part of the predefined constants triggers
+// a compile-time error.
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
// Modules build produces a different error ("Could not build module 'std'").
// UNSUPPORTED: clang-modules-build
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_HARDENED_MODE=2
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=42
#include <cassert>
-// expected-error@*:* {{_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1.}}
+// expected-error@*:* {{_LIBCPP_HARDENING_MODE must be set to one of the following values: _LIBCPP_HARDENING_MODE_UNCHECKED, _LIBCPP_HARDENING_MODE_HARDENED, _LIBCPP_HARDENING_MODE_DEBUG_LITE, _LIBCPP_HARDENING_MODE_DEBUG}}
diff --git a/libcxx/test/libcxx/assertions/modes/override_with_debug_lite_mode.pass.cpp b/libcxx/test/libcxx/assertions/modes/override_with_debug_lite_mode.pass.cpp
new file mode 100644
index 000000000000000..32f6a90089625bc
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/modes/override_with_debug_lite_mode.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override any hardening mode with the debug-lite mode on a per-TU basis.
+
+// `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_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG_LITE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] {
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(false, "Debug-lite-mode assertions should fire");
+ }(), "Debug-lite-mode assertions should fire");
+ _LIBCPP_ASSERT_INTERNAL(false, "Debug-mode assertions should not fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/override_with_debug_mode.pass.cpp
similarity index 52%
rename from libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp
rename to libcxx/test/libcxx/assertions/modes/override_with_debug_mode.pass.cpp
index 78373b992569cb4..caf28371f0a5c49 100644
--- a/libcxx/test/libcxx/assertions/modes/debug_mode_enabled_in_tu.pass.cpp
+++ b/libcxx/test/libcxx/assertions/modes/override_with_debug_mode.pass.cpp
@@ -6,24 +6,24 @@
//
//===----------------------------------------------------------------------===//
-// This test ensures that we can enable the debug mode on a per-TU basis.
+// This test ensures that we can override any hardening mode with the debug mode on a per-TU basis.
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
-// `check_assertion.h` is only available starting from C++11 and requires Unix headers.
-// UNSUPPORTED: c++03, !has-unix-headers
+// `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_DEBUG_MODE=1
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ _LIBCPP_ASSERT_INTERNAL(true, "Should not fire");
TEST_LIBCPP_ASSERT_FAILURE([] {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire");
- }(), "Should fire");
+ _LIBCPP_ASSERT_INTERNAL(false, "Debug-mode assertions should fire");
+ }(), "Debug-mode assertions should fire");
return 0;
}
diff --git a/libcxx/test/libcxx/assertions/modes/safe_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/override_with_hardened_mode.pass.cpp
similarity index 66%
rename from libcxx/test/libcxx/assertions/modes/safe_mode_enabled_in_tu.pass.cpp
rename to libcxx/test/libcxx/assertions/modes/override_with_hardened_mode.pass.cpp
index 4f9b236f920db4e..3f38b368aef4bfe 100644
--- a/libcxx/test/libcxx/assertions/modes/safe_mode_enabled_in_tu.pass.cpp
+++ b/libcxx/test/libcxx/assertions/modes/override_with_hardened_mode.pass.cpp
@@ -6,17 +6,15 @@
//
//===----------------------------------------------------------------------===//
-// This test ensures that we can enable the safe mode on a per-TU basis.
+// This test ensures that we can override any hardening mode with the hardened mode on a per-TU basis.
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
// `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_SAFE_MODE=1
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_HARDENED
#include <cassert>
#include "check_assertion.h"
@@ -24,8 +22,9 @@
int main(int, char**) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
TEST_LIBCPP_ASSERT_FAILURE([] {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire");
- }(), "Should fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Hardened-mode assertions should fire");
+ }(), "Hardened-mode assertions should fire");
+ _LIBCPP_ASSERT_INTERNAL(false, "Debug-mode assertions should not fire");
return 0;
}
diff --git a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/override_with_unchecked_mode.pass.cpp
similarity index 66%
rename from libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp
rename to libcxx/test/libcxx/assertions/modes/override_with_unchecked_mode.pass.cpp
index e652ee338ca8e96..56df977eff86ecf 100644
--- a/libcxx/test/libcxx/assertions/modes/hardened_mode_enabled_in_tu.pass.cpp
+++ b/libcxx/test/libcxx/assertions/modes/override_with_unchecked_mode.pass.cpp
@@ -6,26 +6,22 @@
//
//===----------------------------------------------------------------------===//
-// This test ensures that we can enable the hardened mode on a per-TU basis.
+// This test ensures that we can override any hardening mode with the unchecked mode on a per-TU basis.
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
// `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_HARDENING_MODE=_LIBCPP_HARDENING_MODE_UNCHECKED
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
- TEST_LIBCPP_ASSERT_FAILURE([] {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire");
- }(), "Should fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
return 0;
}
diff --git a/libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp b/libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp
deleted file mode 100644
index 5ef9bab0abe66fd..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/safe_and_debug_mutually_exclusive.verify.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// 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: clang-modules-build
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=1 -D_LIBCPP_ENABLE_DEBUG_MODE=1
-
-#include <cassert>
-
-// 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/safe_mode_disabled_in_tu.pass.cpp b/libcxx/test/libcxx/assertions/modes/safe_mode_disabled_in_tu.pass.cpp
deleted file mode 100644
index 81d155705f1924e..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/safe_mode_disabled_in_tu.pass.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// This test ensures that we can disable the safe mode on a per-TU basis.
-
-// Other hardening modes would still make the assertions fire (disabling the safe mode doesn't disable e.g. the debug
-// mode).
-// REQUIRES: libcpp-hardening-mode=safe
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=0
-
-#include <cassert>
-
-int main(int, char**) {
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
-
- return 0;
-}
diff --git a/libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp b/libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp
deleted file mode 100644
index 578d1123a3e80dc..000000000000000
--- a/libcxx/test/libcxx/assertions/modes/safe_mode_not_1_or_0.verify.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// This test verifies that setting the safe mode to a value other than `0` or `1` triggers a compile-time error.
-
-// Other hardening modes would additionally trigger the error that they are mutually exclusive.
-// REQUIRES: libcpp-hardening-mode=unchecked
-// Modules build produces a different error ("Could not build module 'std'").
-// UNSUPPORTED: clang-modules-build
-// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_SAFE_MODE=2
-
-#include <cassert>
-
-// expected-error@*:* {{_LIBCPP_ENABLE_SAFE_MODE must be set to 0 or 1.}}
diff --git a/libcxx/test/libcxx/odr_signature.hardening.sh.cpp b/libcxx/test/libcxx/odr_signature.hardening.sh.cpp
index 3ae95c8910a9296..c01159eb9fbe363 100644
--- a/libcxx/test/libcxx/odr_signature.hardening.sh.cpp
+++ b/libcxx/test/libcxx/odr_signature.hardening.sh.cpp
@@ -6,23 +6,17 @@
//
//===----------------------------------------------------------------------===//
-// TODO: Remove these UNSUPPORTED lines once we change how hardening is enabled to avoid
-// mutually exclusive modes being enabled at the same time.
-// UNSUPPORTED: libcpp-hardening-mode=hardened
-// UNSUPPORTED: libcpp-hardening-mode=safe
-// UNSUPPORTED: libcpp-hardening-mode=debug
-
// TODO: Investigate
// XFAIL: msvc
// Test that we encode the hardening mode in an ABI tag to avoid ODR violations
// when linking TUs that have different values for it.
-// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -D_LIBCPP_ENABLE_HARDENED_MODE -o %t.tu1.o
-// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -D_LIBCPP_ENABLE_SAFE_MODE -o %t.tu2.o
-// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -D_LIBCPP_ENABLE_DEBUG_MODE -o %t.tu3.o
-// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -o %t.tu4.o
-// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_HARDENED -o %t.tu1.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG_LITE -o %t.tu2.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG -o %t.tu3.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -Wno-macro-redefined -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_UNCHECKED -o %t.tu4.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o
// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.tu3.o %t.tu4.o %t.main.o %{flags} %{link_flags} -o %t.exe
// RUN: %{exec} %t.exe
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/complexity.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/complexity.pass.cpp
index 47b4f3bb19329f5..dbf7b534069517a 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/complexity.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/complexity.pass.cpp
@@ -68,7 +68,7 @@ int main(int, char**) {
std::sort_heap(first, last);
LIBCPP_ASSERT(stats.copied == 0);
LIBCPP_ASSERT(stats.moved <= 2 * n + n * logn);
-#if !_LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
LIBCPP_ASSERT(stats.compared <= n * logn);
(void)debug_comparisons;
#else
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
index 5723ed0d3db25e4..2231b07e09eee17 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
@@ -262,7 +262,7 @@ void test_complexity() {
std::ranges::sort_heap(first, last, &MyInt::Comp);
LIBCPP_ASSERT(stats.copied == 0);
LIBCPP_ASSERT(stats.moved <= 2 * n + n * logn);
-#if !_LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
LIBCPP_ASSERT(stats.compared <= n * logn);
(void)debug_comparisons;
#else
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
index c82ad2623ee8b50..0a35fad40e89a54 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
@@ -79,7 +79,7 @@ test_one(unsigned N, unsigned M)
assert(ia[0] == static_cast<int>(N)-1);
assert(ia[N-1] == 0);
assert(std::is_sorted(ia, ia+N, std::greater<value_type>()));
-#if !_LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
assert(pred.count() <= (N-1));
#endif
}
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
index dd413cfbaa2a92d..d3c2814d642a7d4 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
@@ -156,7 +156,7 @@ constexpr void test_comparator_invocation_count() {
// The comparator is invoked only `min(left.size(), right.size())` times
test_lexicographical_compare<const int*, const int*>(
std::array{0, 1, 2}, std::array{0, 1, 2, 3}, compare_last_digit_counting, std::strong_ordering::less);
-#if !_LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
assert(compare_invocation_count <= 3);
#else
assert(compare_invocation_count <= 6);
diff --git a/libcxx/test/support/container_debug_tests.h b/libcxx/test/support/container_debug_tests.h
index 07db855e58dc4a9..c35da37a87da6eb 100644
--- a/libcxx/test/support/container_debug_tests.h
+++ b/libcxx/test/support/container_debug_tests.h
@@ -14,7 +14,7 @@
#error This header may only be used for libc++ tests
#endif
-#if !_LIBCPP_ENABLE_DEBUG_MODE
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
#error The library must be built with the debug mode enabled in order to use this header
#endif
diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml
index 5a5bc39c5797bdd..a3ef9a2738b04bc 100644
--- a/libcxx/utils/ci/buildkite-pipeline.yml
+++ b/libcxx/utils/ci/buildkite-pipeline.yml
@@ -422,8 +422,8 @@ steps:
limit: 2
timeout_in_minutes: 120
- - label: "Safe mode"
- command: "libcxx/utils/ci/run-buildbot generic-safe-mode"
+ - label: "Debug-lite mode"
+ command: "libcxx/utils/ci/run-buildbot generic-debug-lite-mode"
artifact_paths:
- "**/test-results.xml"
- "**/*.abilist"
diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py
index 2ead641354e585d..c0532eb9f85765e 100644
--- a/libcxx/utils/libcxx/test/params.py
+++ b/libcxx/utils/libcxx/test/params.py
@@ -287,7 +287,7 @@ def getStdFlag(cfg, std):
),
Parameter(
name="hardening_mode",
- choices=["unchecked", "hardened", "safe", "debug"],
+ choices=["unchecked", "hardened", "debug_lite", "debug"],
type=str,
default="unchecked",
help="Whether to enable one of the hardening modes when compiling the test suite. This is only "
@@ -295,9 +295,10 @@ def getStdFlag(cfg, std):
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,
+ AddCompileFlag("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_HARDENED") if hardening_mode == "hardened" else None,
+ AddCompileFlag("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG_LITE") if hardening_mode == "debug_lite" else None,
+ AddCompileFlag("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG") if hardening_mode == "debug" else None,
+ AddCompileFlag("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_UNCHECKED") if hardening_mode == "unchecked" else None,
AddFeature("libcpp-hardening-mode={}".format(hardening_mode)),
],
),
diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index 50969e0f3f2ae17..76de0eb769d1155 100644
--- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -35,9 +35,7 @@ if (current_toolchain == default_toolchain) {
"_LIBCPP_HAS_NO_WIDE_CHARACTERS=",
"_LIBCPP_HAS_NO_STD_MODULES=",
"_LIBCPP_ABI_DEFINES=",
- "_LIBCPP_ENABLE_DEBUG_MODE_DEFAULT=",
- "_LIBCPP_ENABLE_HARDENED_MODE_DEFAULT=",
- "_LIBCPP_ENABLE_SAFE_MODE_DEFAULT=",
+ "_LIBCPP_HARDENING_MODE_DEFAULT=",
"_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH=",
"_LIBCPP_PSTL_CPU_BACKEND_SERIAL=1",
"_LIBCPP_PSTL_CPU_BACKEND_THREAD=",
More information about the libcxx-commits
mailing list