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 hardened_plus 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_HARDENED_PLUS_MODE_DEFAULT) + config_define(0 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT) +elseif (LIBCXX_HARDENING_MODE STREQUAL "hardened_plus") + config_define(0 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT) + config_define(1 _LIBCPP_ENABLE_HARDENED_PLUS_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_HARDENED_PLUS_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_HARDENED_PLUS_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=hardened_plus") endif() if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "serial") diff --git a/libcxx/include/__algorithm/three_way_comp_ref_type.h b/libcxx/include/__algorithm/three_way_comp_ref_type.h --- a/libcxx/include/__algorithm/three_way_comp_ref_type.h +++ b/libcxx/include/__algorithm/three_way_comp_ref_type.h @@ -50,7 +50,7 @@ __expected = _Order::greater; if (__o == _Order::greater) __expected = _Order::less; - _LIBCPP_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); + _LIBCPP_ASSERT_UNCATEGORIZED(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); (void)__l; (void)__r; } 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 hardened-plus 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_HARDENED_PLUS_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_HARDENED_PLUS_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_HARDENED_PLUS_MODE` and `_LIBCPP_ENABLE_DEBUG_MODE`. // // #define _LIBCPP_ENABLE_HARDENED_MODE 1 +// Enables the hardened-plus 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_HARDENED_PLUS_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_HARDENED_PLUS_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_HARDENED_PLUS_MODE +# define _LIBCPP_ENABLE_HARDENED_PLUS_MODE _LIBCPP_ENABLE_HARDENED_PLUS_MODE_DEFAULT +# endif +# if _LIBCPP_ENABLE_HARDENED_PLUS_MODE != 0 && _LIBCPP_ENABLE_HARDENED_PLUS_MODE != 1 +# error "_LIBCPP_ENABLE_HARDENED_PLUS_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,15 @@ # 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_HARDENED_PLUS_MODE) || \ + (_LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE) || \ + (_LIBCPP_ENABLE_HARDENED_PLUS_MODE && _LIBCPP_ENABLE_DEBUG_MODE) +# error "Only one of _LIBCPP_ENABLE_HARDENED_MODE, _LIBCPP_ENABLE_HARDENED_PLUS_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 +306,20 @@ # define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) # define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) +// Hardened-plus mode checks. + +# elif _LIBCPP_ENABLE_HARDENED_PLUS_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 hardened-plus 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_HARDENED_PLUS_MODE_DEFAULT #cmakedefine01 _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT // __USE_MINGW_ANSI_STDIO gets redefined on MinGW