diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index 41a2aad1da236..ec937de02ca1a 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -128,7 +128,6 @@ jobs: 'generic-abi-unstable', 'generic-hardening-mode-debug', 'generic-hardening-mode-extensive', - 'generic-hardening-mode-extensive-observe-semantic', 'generic-hardening-mode-fast', 'generic-hardening-mode-fast-with-abi-breaks', 'generic-merged', diff --git a/libcxx/cmake/caches/Generic-hardening-mode-extensive-observe-semantic.cmake b/libcxx/cmake/caches/Generic-hardening-mode-extensive-observe-semantic.cmake deleted file mode 100644 index c843c02977a87..0000000000000 --- a/libcxx/cmake/caches/Generic-hardening-mode-extensive-observe-semantic.cmake +++ /dev/null @@ -1,2 +0,0 @@ -set(LIBCXX_HARDENING_MODE "extensive" CACHE STRING "") -set(LIBCXX_TEST_PARAMS "assertion_semantic=observe" CACHE STRING "") diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst index 0aecac309acd9..17808841bd9ec 100644 --- a/libcxx/docs/Hardening.rst +++ b/libcxx/docs/Hardening.rst @@ -39,8 +39,6 @@ modes are: Enabling hardening has no impact on the ABI. -.. _notes-for-users: - Notes for users --------------- @@ -74,11 +72,6 @@ to control the level by passing **one** of the following options to the compiler pre-built components. Most libc++ code is header-based, so a user-provided value for ``_LIBCPP_HARDENING_MODE`` will be mostly respected. -In some cases, users might want to override the assertion semantic used by the -library. -This can be done similarly to setting the hardening mode; please refer to the -:ref:`relevant section `. - Notes for vendors ----------------- @@ -267,60 +260,6 @@ output. This is less secure and increases the size of the binary (among other things, it has to store the error message strings) but makes the failure easier to debug. It also allows testing the error messages in our test suite. -This default behavior can be customized by users via :ref:`assertion semantics -`; it can also be completely overridden by vendors by -providing a :ref:`custom assertion failure handler -`. - -.. _assertion-semantics: - -Assertion semantics -------------------- - -What happens when an assertion fails depends on the assertion semantic being -used. Four assertion semantics are available, based on C++26 Contracts -evaluation semantics: - -- ``ignore`` evaluates the assertion but has no effect if it fails (note that it - differs from the Contracts ``ignore`` semantic which would not evaluate - the assertion at all); -- ``observe`` logs an error (indicating, if possible on the platform, that the - error is fatal) but continues execution; -- ``quick-enforce`` terminates the program as fast as possible via a trap - instruction. It is the default semantic for the production modes (``fast`` and - ``extensive``); -- ``enforce`` logs an error and then terminates the program. It is the default - semantic for the ``debug`` mode. - -Notes: - -- Continuing execution after a hardening check fails results in undefined - behavior; the ``observe`` semantic is meant to make adopting hardening easier - but should not be used outside of the adoption period; -- C++26 wording for Library Hardening precludes a conforming Hardened - implementation from using the Contracts ``ignore`` semantic when evaluating - hardened preconditions in the Library. Libc++ allows using this semantic for - hardened preconditions, but please be aware that using ``ignore`` does not - produce a conforming "Hardened" implementation, unlike the other semantics - above. - -The default assertion semantics are as follows: - -- ``fast``: ``quick-enforce``; -- ``extensive``: ``quick-enforce``; -- ``debug``: ``enforce``. - -The default assertion semantics can be overridden by passing **one** of the -following options to the compiler: - -- ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE`` -- ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE`` -- ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE`` -- ``-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE`` - -All the :ref:`same notes ` apply to setting this macro as for -setting ``_LIBCPP_HARDENING_MODE``. - .. _override-assertion-handler: Overriding the assertion failure handler diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst index 0bb73a1c0196d..6f18b61284f49 100644 --- a/libcxx/docs/ReleaseNotes/21.rst +++ b/libcxx/docs/ReleaseNotes/21.rst @@ -88,11 +88,6 @@ Improvements and New Features - ``ctype::tolower`` and ``ctype::toupper`` have been optimized, resulting in a 2x performance improvement. -- Hardening now supports assertion semantics that allow customizing how a hardening assertion failure is handled. The - four available semantics, modeled on C++26 Contracts, are ``ignore``, ``observe``, ``quick-enforce`` and ``enforce``. - The ``observe`` semantic is intended to make it easier to adopt Hardening in production but should not be used outside - of this scenario. Please refer to the :ref:`Hardening documentation ` for details. - Deprecations and Removals ------------------------- diff --git a/libcxx/include/__config b/libcxx/include/__config index ef0c8b48b658b..d940461c30234 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -147,40 +147,6 @@ _LIBCPP_HARDENING_MODE_EXTENSIVE, \ _LIBCPP_HARDENING_MODE_DEBUG # endif -// Hardening assertion semantics generally mirror the evaluation semantics of C++26 Contracts: -// - `ignore` evaluates the assertion but doesn't do anything if it fails (note that it differs from the Contracts -// `ignore` semantic which wouldn't evaluate the assertion at all); -// - `observe` logs an error (indicating, if possible, that the error is fatal) and continues execution; -// - `quick-enforce` terminates the program as fast as possible (via trapping); -// - `enforce` logs an error and then terminates the program. -// -// Notes: -// - Continuing execution after a hardening check fails results in undefined behavior; the `observe` semantic is meant -// to make adopting hardening easier but should not be used outside of this scenario; -// - C++26 wording for Library Hardening precludes a conforming Hardened implementation from using the Contracts -// `ignore` semantic when evaluating hardened preconditions in the Library. Libc++ allows using this semantic for -// hardened preconditions, however, be aware that using `ignore` does not produce a conforming "Hardened" -// implementation, unlike the other semantics above. -// clang-format off -# define _LIBCPP_ASSERTION_SEMANTIC_IGNORE (1 << 1) -# define _LIBCPP_ASSERTION_SEMANTIC_OBSERVE (1 << 2) -# define _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE (1 << 3) -# define _LIBCPP_ASSERTION_SEMANTIC_ENFORCE (1 << 4) -// clang-format on - -// Allow users to define an arbitrary assertion semantic; otherwise, use the default mapping from modes to semantics. -// The default is for production-capable modes to use `quick-enforce` (i.e., trap) and for the `debug` mode to use -// `enforce` (i.e., log and abort). -# ifndef _LIBCPP_ASSERTION_SEMANTIC - -# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG -# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_ENFORCE -# else -# define _LIBCPP_ASSERTION_SEMANTIC _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -# endif - -# endif // _LIBCPP_ASSERTION_SEMANTIC - // } HARDENING # define _LIBCPP_TOSTRING2(x) #x diff --git a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp index 1c9829837ae62..90cb0c84a063b 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp @@ -43,17 +43,17 @@ int main(int, char**) { } // mismatch of static extent { - TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents e1(std::array{1000, 3}); }()), + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(std::array{1000, 3}); }()), "extents construction: mismatch of provided arguments with static extents."); } // value out of range { - TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents e1(std::array{1000, 5}); }()), + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(std::array{1000, 5}); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); } // negative value { - TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents e1(std::array{-1, 5}); }()), + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(std::array{-1, 5}); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); } return 0; diff --git a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp index 17bab03b922e6..37e79aabf8532 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp @@ -45,17 +45,17 @@ int main(int, char**) { } // mismatch of static extent { - TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents e1(1000, 3); }()), + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(1000, 3); }()), "extents construction: mismatch of provided arguments with static extents."); } // value out of range { - TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents e1(1000, 5); }()), + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(1000, 5); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); } // negative value { - TEST_LIBCPP_ASSERT_FAILURE(([] { [[maybe_unused]] std::extents e1(-1, 5); }()), + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(-1, 5); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); } return 0; diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp index c67529671fcf7..7b6616f19d724 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp @@ -44,7 +44,7 @@ int main(int, char**) { { TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_left::mapping> m( + std::layout_left::mapping> m( std::layout_left::mapping>(std::extents(500))); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); @@ -55,7 +55,7 @@ int main(int, char**) { [[maybe_unused]] std::extents e(arg_exts); // but the product is not, so we can't use it for layout_left TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_left::mapping> m(arg); }()), + ([=] { std::layout_left::mapping> m(arg); }()), "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type."); } return 0; diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp index 45f07f1ed5c06..7c96f8ec9353f 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp @@ -31,10 +31,7 @@ int main(int, char**) { { // the extents are representable but the product is not, so we can't use it for layout_left TEST_LIBCPP_ASSERT_FAILURE( - ([=] { - [[maybe_unused]] std::layout_left::mapping> m( - std::extents(100)); - }()), + ([=] { std::layout_left::mapping> m(std::extents(100)); }()), "layout_left::mapping extents ctor: product of extents must be representable as index_type."); } return 0; diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp index 04a6c59d265e1..e578bac2103b0 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp @@ -39,14 +39,14 @@ int main(int, char**) { } // mismatch of static extent { - TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_left::mapping> m(arg); }()), + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping> m(arg); }()), "extents construction: mismatch of provided arguments with static extents."); } // non-representability of extents itself { TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_left::mapping> m( + std::layout_left::mapping> m( std::layout_right::mapping>(std::extents(500))); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp index 81fc8b5d65e62..df16edb925407 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp @@ -37,14 +37,14 @@ int main(int, char**) { } // mismatch of static extent { - TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_right::mapping> m(arg); }()), + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping> m(arg); }()), "extents construction: mismatch of provided arguments with static extents."); } // non-representability of extents itself { TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_right::mapping> m( + std::layout_right::mapping> m( std::layout_right::mapping>(std::extents(500))); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); @@ -55,7 +55,7 @@ int main(int, char**) { [[maybe_unused]] std::extents e(arg_exts); // but the product is not, so we can't use it for layout_right TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_right::mapping> m(arg); }()), + ([=] { std::layout_right::mapping> m(arg); }()), "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type."); } return 0; diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp index 33b71fdfd052d..52095691f6d24 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp @@ -32,8 +32,7 @@ int main(int, char**) { // the extents are representable but the product is not, so we can't use it for layout_right TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_right::mapping> m( - std::extents(100)); + std::layout_right::mapping> m(std::extents(100)); }()), "layout_right::mapping extents ctor: product of extents must be representable as index_type."); } diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp index 32972771f242d..1757ddb286b9c 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp @@ -39,14 +39,14 @@ int main(int, char**) { } // mismatch of static extent { - TEST_LIBCPP_ASSERT_FAILURE(([=] { [[maybe_unused]] std::layout_right::mapping> m(arg); }()), + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping> m(arg); }()), "extents construction: mismatch of provided arguments with static extents."); } // non-representability of extents itself { TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_right::mapping> m( + std::layout_right::mapping> m( std::layout_left::mapping>(std::extents(500))); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp index 354db1d3cc3cc..7deb1215de0de 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp @@ -58,15 +58,14 @@ int main(int, char**) { { std::extents arg_exts{100, 5}; std::layout_stride::mapping> arg(arg_exts, std::array{1, 100}); - TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_stride::mapping> m(arg); }()), - "extents construction: mismatch of provided arguments with static extents."); + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping> m(arg); }()), + "extents construction: mismatch of provided arguments with static extents."); } // non-representability of extents itself { TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::layout_stride::mapping>(std::extents(500), std::array{1})); }()), "extents ctor: arguments must be representable as index_type and nonnegative"); @@ -74,9 +73,8 @@ int main(int, char**) { // all strides must be larger than zero { always_convertible_layout::mapping> offset_map(std::dextents{10, 10}, 100, -1); - TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_stride::mapping> m(offset_map); }()), - "layout_stride::mapping converting ctor: all strides must be greater than 0"); + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping> m(offset_map); }()), + "layout_stride::mapping converting ctor: all strides must be greater than 0"); } // required_span_size not representable, while individual extents are { @@ -86,7 +84,7 @@ int main(int, char**) { [[maybe_unused]] std::extents e(arg_exts); // but the product is not, so we can't use it for layout_stride TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_stride::mapping> m(arg); }()), + ([=] { std::layout_stride::mapping> m(arg); }()), "layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type."); } // required_span_size not representable, while individual extents are, edge case @@ -100,15 +98,14 @@ int main(int, char**) { [[maybe_unused]] std::extents e(arg_exts); // but the product is not, so we can't use it for layout_stride TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_stride::mapping> m(arg); }()), + ([=] { std::layout_stride::mapping> m(arg); }()), "layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type."); } // base offset must be 0 (i.e. mapping(0,...,0)==0) for a strided layout with positive strides { always_convertible_layout::mapping> offset_map(std::dextents{10, 10}, 3); - TEST_LIBCPP_ASSERT_FAILURE( - ([=] { [[maybe_unused]] std::layout_stride::mapping> m(offset_map); }()), - "layout_stride::mapping converting ctor: base offset of mapping must be zero."); + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping> m(offset_map); }()), + "layout_stride::mapping converting ctor: base offset of mapping must be zero."); } return 0; } diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp index a6120f8bf9c4b..97a6d56e4f839 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp @@ -42,7 +42,7 @@ int main(int, char**) { { TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::extents(20), std::array{4, 1, 200}); }()), "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping"); @@ -58,7 +58,7 @@ int main(int, char**) { // will fail because neither of the equal strides is associated with an extent of 1 TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m3( + std::layout_stride::mapping> m3( std::extents(2), std::array{5, 1, 5}); }()), "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping"); diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp index 9c52dd411b7c5..860849ded2de2 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp @@ -42,7 +42,7 @@ int main(int, char**) { // the extents are representable but the product with strides is not, so we can't use it for layout_stride TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::extents(20), std::array{20, 1}); }()), "layout_stride::mapping ctor: required span size is not representable as index_type."); @@ -51,7 +51,7 @@ int main(int, char**) { static_assert(static_cast(257u) == 1); TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::extents(20), std::array{257, 1}); }()), "layout_stride::mapping ctor: required span size is not representable as index_type."); @@ -59,14 +59,14 @@ int main(int, char**) { // negative strides are not allowed, check with unsigned index_type so we make sure we catch that TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::extents(20), std::array{20, -1}); }()), "layout_stride::mapping ctor: all strides must be greater than 0"); // zero strides are not allowed, check with unsigned index_type so we make sure we catch that TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::extents(20), std::array{20, 0}); }()), "layout_stride::mapping ctor: all strides must be greater than 0"); diff --git a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp index 4752d3946aece..fd0701e9ee3a7 100644 --- a/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp +++ b/libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp @@ -43,7 +43,7 @@ int main(int, char**) { TEST_LIBCPP_ASSERT_FAILURE( ([=] { std::array strides{4, 1, 200}; - [[maybe_unused]] std::layout_stride::mapping> m( + std::layout_stride::mapping> m( std::extents(20), std::span(strides)); }()), "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping"); @@ -61,7 +61,7 @@ int main(int, char**) { // will fail because neither of the equal strides is associated with an extent of 1 TEST_LIBCPP_ASSERT_FAILURE( ([=] { - [[maybe_unused]] std::layout_stride::mapping> m3( + std::layout_stride::mapping> m3( std::extents(2), std::span(strides)); }()), "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping"); diff --git a/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp b/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp index 2bc4648878f8e..419a603a037f8 100644 --- a/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.barrier/assert.arrive.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: no-threads // UNSUPPORTED: c++03, c++11, c++14, c++17 // REQUIRES: libcpp-hardening-mode={{extensive|debug}} -// Without the assertion, the test will most likely time out. -// UNSUPPORTED: libcpp-assertion-semantic={{ignore|observe}} // XFAIL: libcpp-hardening-mode=debug && 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 index 30d36b5f6d7b5..e61679554a62e 100644 --- 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 @@ -18,8 +18,6 @@ // REQUIRES: has-unix-headers // REQUIRES: libcpp-hardening-mode={{extensive|debug}} -// Without the assertion, the test will most likely time out. -// UNSUPPORTED: libcpp-assertion-semantic={{ignore|observe}} // XFAIL: libcpp-hardening-mode=debug && 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 index 01fb907c3fbd4..5f1ea19d82a50 100644 --- a/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp @@ -24,12 +24,11 @@ #include "check_assertion.h" -int main(int, char**) { +int main(int, char **) { { - TEST_LIBCPP_ASSERT_FAILURE( - [] { [[maybe_unused]] std::latch l(-1); }(), - "latch::latch(ptrdiff_t): latch cannot be " - "initialized with a negative value"); + TEST_LIBCPP_ASSERT_FAILURE([]{ std::latch l(-1); }(), + "latch::latch(ptrdiff_t): latch cannot be " + "initialized with a negative value"); } // We can't check the precondition for max() because there's no value diff --git a/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp index c490948d36abe..1e33add779496 100644 --- a/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp +++ b/libcxx/test/libcxx/thread/thread.semaphore/assert.ctor.pass.cpp @@ -26,7 +26,7 @@ int main(int, char**) { { TEST_LIBCPP_ASSERT_FAILURE( - [] { [[maybe_unused]] std::counting_semaphore<> s(-1); }(), + [] { std::counting_semaphore<> s(-1); }(), "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " "initialized with a negative value"); } diff --git a/libcxx/test/support/check_assertion.h b/libcxx/test/support/check_assertion.h index a091043195345..a279400d651b4 100644 --- a/libcxx/test/support/check_assertion.h +++ b/libcxx/test/support/check_assertion.h @@ -44,32 +44,15 @@ static constexpr const char* Marker = "###"; using MatchResult = std::pair; using Matcher = std::function; -// Using the marker makes matching more precise, but we cannot output the marker when the `observe` semantic is used -// (because it doesn't allow customizing the logging function). If the marker is not available, fall back to using less -// precise matching by just the error message. -MatchResult MatchAssertionMessage(const std::string& text, std::string_view expected_message, bool use_marker) { +MatchResult MatchAssertionMessage(const std::string& text, std::string_view expected_message) { // Extract information from the error message. This has to stay synchronized with how we format assertions in the // library. - std::string assertion_format_string = [&] { - if (use_marker) - return (".*###\\n(.*):(\\d+): assertion (.*) failed: (.*)\\n###"); - return ("(.*):(\\d+): assertion (.*) failed: (.*)\\n"); - }(); - std::regex assertion_format(assertion_format_string); + std::regex assertion_format(".*###\\n(.*):(\\d+): assertion (.*) failed: (.*)\\n###"); std::smatch match_result; - // If a non-terminating assertion semantic is used, more than one assertion might be triggered before the process - // dies, so we cannot expect the entire target string to match. - bool has_match = std::regex_search(text, match_result, assertion_format); - if (!has_match || match_result.size() != 5) { - std::stringstream matching_error; - matching_error // - << "Failed to parse the assertion message.\n" // - << "Using marker: " << use_marker << "\n" // - << "Expected message: '" << expected_message.data() << "'\n" // - << "Stderr contents: '" << text.c_str() << "'\n"; - return MatchResult(/*success=*/false, matching_error.str()); - } + bool has_match = std::regex_match(text, match_result, assertion_format); + assert(has_match); + assert(match_result.size() == 5); const std::string& file = match_result[1]; int line = std::stoi(match_result[2]); @@ -89,9 +72,9 @@ MatchResult MatchAssertionMessage(const std::string& text, std::string_view expe return MatchResult(/*success=*/true, /*maybe_error=*/""); } -Matcher MakeAssertionMessageMatcher(std::string_view assertion_message, bool use_marker = true) { +Matcher MakeAssertionMessageMatcher(std::string_view assertion_message) { return [=](const std::string& text) { // - return MatchAssertionMessage(text, assertion_message, use_marker); + return MatchAssertionMessage(text, assertion_message); }; } @@ -102,17 +85,13 @@ Matcher MakeAnyMatcher() { } enum class DeathCause { - // Valid causes. + // Valid causes VerboseAbort = 1, StdAbort, StdTerminate, Trap, - // Causes that might be invalid or might stem from undefined behavior (relevant for non-terminating assertion - // semantics). + // Invalid causes DidNotDie, - Segfault, - ArithmeticError, - // Always invalid causes. SetupFailure, Unknown }; @@ -129,16 +108,6 @@ bool IsValidCause(DeathCause cause) { } } -bool IsTestSetupErrorCause(DeathCause cause) { - switch (cause) { - case DeathCause::SetupFailure: - case DeathCause::Unknown: - return true; - default: - return false; - } -} - std::string ToString(DeathCause cause) { switch (cause) { case DeathCause::VerboseAbort: @@ -151,14 +120,10 @@ std::string ToString(DeathCause cause) { return "trap"; case DeathCause::DidNotDie: return ""; - case DeathCause::Segfault: - return ""; - case DeathCause::ArithmeticError: - return ""; case DeathCause::SetupFailure: - return ""; + return ""; case DeathCause::Unknown: - return ""; + return ""; } assert(false && "Unreachable"); @@ -260,38 +225,9 @@ class DeathTest { return DeathTestResult(Outcome::Success, cause); } - // When non-terminating assertion semantics are used, the program will invoke UB which might or might not crash the - // process; we make sure that the execution produces the expected error message but otherwise consider the test run - // successful whether the child process dies or not. - template - DeathTestResult RunWithoutGuaranteedDeath(Func&& func, const Matcher& matcher) { - std::signal(SIGABRT, [](int) { StopChildProcess(DeathCause::StdAbort); }); - std::set_terminate([] { StopChildProcess(DeathCause::StdTerminate); }); - - DeathCause cause = Run(func); - - if (IsTestSetupErrorCause(cause)) { - return DeathTestResult(Outcome::InvalidCause, cause, ToString(cause)); - } - - MatchResult match_result = matcher(GetChildStdErr()); - if (!match_result.first) { - auto failure_description = std::string("Child produced a different error message\n") + match_result.second; - return DeathTestResult(Outcome::UnexpectedErrorMessage, cause, failure_description); - } - - return DeathTestResult(Outcome::Success, cause); - } - - void PrintFailureDetails(std::string_view invocation, - std::string_view failure_description, - std::string_view stmt, - DeathCause cause) const { - std::fprintf(stderr, - "Failure: %s( %s ) failed!\n(reason: %s)\n\n", - invocation.data(), - stmt.data(), - failure_description.data()); + void PrintFailureDetails(std::string_view failure_description, std::string_view stmt, DeathCause cause) const { + std::fprintf( + stderr, "Failure: EXPECT_DEATH( %s ) failed!\n(reason: %s)\n\n", stmt.data(), failure_description.data()); if (cause != DeathCause::Unknown) { std::fprintf(stderr, "child exit code: %d\n", GetChildExitCode()); @@ -375,16 +311,10 @@ class DeathTest { if (WIFSIGNALED(status_value)) { exit_code_ = WTERMSIG(status_value); - // `__builtin_trap` generates `SIGILL` on x86 and `SIGTRAP` on ARM. + // `__builtin_trap` generqtes `SIGILL` on x86 and `SIGTRAP` on ARM. if (exit_code_ == SIGILL || exit_code_ == SIGTRAP) { return DeathCause::Trap; } - if (exit_code_ == SIGSEGV) { - return DeathCause::Segfault; - } - if (exit_code_ == SIGFPE) { - return DeathCause::ArithmeticError; - } } return DeathCause::Unknown; @@ -427,7 +357,7 @@ bool ExpectDeath( DeathTest test_case; DeathTestResult test_result = test_case.Run(expected_causes, func, matcher); if (!test_result.success()) { - test_case.PrintFailureDetails("EXPECT_DEATH", test_result.failure_description(), stmt, test_result.cause()); + test_case.PrintFailureDetails(test_result.failure_description(), stmt, test_result.cause()); } return test_result.success(); @@ -448,22 +378,6 @@ bool ExpectDeath(DeathCause expected_cause, const char* stmt, Func&& func) { return ExpectDeath(std::array{expected_cause}, stmt, func, MakeAnyMatcher()); } -template -bool ExpectLog(const char* stmt, Func&& func, const Matcher& matcher) { - DeathTest test_case; - DeathTestResult test_result = test_case.RunWithoutGuaranteedDeath(func, matcher); - if (!test_result.success()) { - test_case.PrintFailureDetails("EXPECT_LOG", test_result.failure_description(), stmt, test_result.cause()); - } - - return test_result.success(); -} - -template -bool ExpectLog(const char* stmt, Func&& func) { - return ExpectLog(stmt, func, MakeAnyMatcher()); -} - // clang-format off /// Assert that the specified expression aborts with the expected cause and, optionally, error message. @@ -478,28 +392,13 @@ bool ExpectLog(const char* stmt, Func&& func) { #define EXPECT_STD_TERMINATE(...) \ assert( ExpectDeath(DeathCause::StdTerminate, #__VA_ARGS__, __VA_ARGS__) ) -#if defined(_LIBCPP_ASSERTION_SEMANTIC) - -#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE +#if defined(_LIBCPP_HARDENING_MODE) && _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG #define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \ assert(( ExpectDeath(DeathCause::VerboseAbort, #expr, [&]() { (void)(expr); }, MakeAssertionMessageMatcher(message)) )) -#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \ - assert(( ExpectDeath(DeathCause::Trap, #expr, [&]() { (void)(expr); }) )) -#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE -#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \ - assert(( ExpectLog(#expr, [&]() { (void)(expr); }, MakeAssertionMessageMatcher(message, /*use_marker=*/false)) )) -#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE -#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \ - assert(( ExpectLog(#expr, [&]() { (void)(expr); }) )) -#else -#error "Unknown value for _LIBCPP_ASSERTION_SEMANTIC" -#endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE - #else #define TEST_LIBCPP_ASSERT_FAILURE(expr, message) \ assert(( ExpectDeath(DeathCause::Trap, #expr, [&]() { (void)(expr); }) )) -#endif // defined(_LIBCPP_ASSERTION_SEMANTIC) +#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG // clang-format on diff --git a/libcxx/test/support/test.support/test_check_assertion.pass.cpp b/libcxx/test/support/test.support/test_check_assertion.pass.cpp index 78e47b32cdd2b..4dfc5319aaf97 100644 --- a/libcxx/test/support/test.support/test_check_assertion.pass.cpp +++ b/libcxx/test/support/test.support/test_check_assertion.pass.cpp @@ -53,7 +53,7 @@ bool TestDeathTest( } if (!maybe_failure_description.empty()) { - test_case.PrintFailureDetails("EXPECT_DEATH", maybe_failure_description, stmt, test_result.cause()); + test_case.PrintFailureDetails(maybe_failure_description, stmt, test_result.cause()); return false; } @@ -76,9 +76,9 @@ DeathCause assertion_death_cause = DeathCause::Trap; #endif int main(int, char**) { - [[maybe_unused]] auto fail_assert = [] { _LIBCPP_ASSERT(false, "Some message"); }; - Matcher good_matcher = MakeAssertionMessageMatcher("Some message"); - Matcher bad_matcher = MakeAssertionMessageMatcher("Bad expected message"); + auto fail_assert = [] { _LIBCPP_ASSERT(false, "Some message"); }; + Matcher good_matcher = MakeAssertionMessageMatcher("Some message"); + Matcher bad_matcher = MakeAssertionMessageMatcher("Bad expected message"); // Test the implementation of death tests. We're bypassing the assertions added by the actual `EXPECT_DEATH` macros // which allows us to test failure cases (where the assertion would fail) as well. @@ -89,22 +89,16 @@ int main(int, char**) { // Success -- trapping. TEST_DEATH_TEST(Outcome::Success, DeathCause::Trap, __builtin_trap()); - // `_LIBCPP_ASSERT` does not terminate the program if the `observe` semantic is used, so these tests would fail with - // `DidNotDie` cause. -#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE - // Success -- assertion failure with any matcher. TEST_DEATH_TEST_MATCHES(Outcome::Success, assertion_death_cause, MakeAnyMatcher(), fail_assert()); // Success -- assertion failure with a specific matcher. TEST_DEATH_TEST_MATCHES(Outcome::Success, assertion_death_cause, good_matcher, fail_assert()); -# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG // Failure -- error message doesn't match. TEST_DEATH_TEST_MATCHES(Outcome::UnexpectedErrorMessage, assertion_death_cause, bad_matcher, fail_assert()); -# endif - -#endif // _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE +#endif // Invalid cause -- child did not die. TEST_DEATH_TEST(Outcome::InvalidCause, DeathCause::DidNotDie, ((void)0)); @@ -131,9 +125,7 @@ int main(int, char**) { EXPECT_DEATH_MATCHES(simple_matcher, invoke_verbose_abort()); EXPECT_STD_ABORT(invoke_abort()); EXPECT_STD_TERMINATE([] { std::terminate(); }); -#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE TEST_LIBCPP_ASSERT_FAILURE(fail_assert(), "Some message"); -#endif } return 0; diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index 57ecf1e49dbf2..d8b23be9a0323 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -442,12 +442,6 @@ generic-hardening-mode-extensive) check-runtimes check-abi-list ;; -generic-hardening-mode-extensive-observe-semantic) - clean - generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-extensive-observe-semantic.cmake" - check-runtimes - check-abi-list -;; generic-hardening-mode-debug) clean generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-debug.cmake" diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index b436ea6ae8a0f..adfb2a9f69508 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -454,24 +454,5 @@ def getSuitableClangTidy(cfg): help="Whether to test the main or C++03-specific headers. Only changes behaviour when std=c++03.", actions=lambda enabled: [] if not enabled else [AddFlag("-D_LIBCPP_USE_FROZEN_CXX03_HEADERS"), AddFeature("FROZEN-CXX03-HEADERS-FIXME")], ), - Parameter( - name='assertion_semantic', - choices=["ignore", "observe", "quick_enforce", "enforce", "undefined"], - type=str, - default="undefined", - help="Whether to override the assertion semantic used by hardening. This is only meaningful when running the " - "tests against libc++ with hardening enabled. By default, no assertion semantic is specified explicitly, so " - "the default one will be used (depending on the hardening mode).", - actions=lambda assertion_semantic: filter( - None, - [ - AddCompileFlag("-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_IGNORE") if assertion_semantic == "ignore" else None, - AddCompileFlag("-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_OBSERVE") if assertion_semantic == "observe" else None, - AddCompileFlag("-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE") if assertion_semantic == "quick_enforce" else None, - AddCompileFlag("-D_LIBCPP_ASSERTION_SEMANTIC=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE") if assertion_semantic == "enforce" else None, - AddFeature("libcpp-assertion-semantic={}".format(assertion_semantic)) if assertion_semantic != "undefined" else None, - ], - ), - ), ] # fmt: on diff --git a/libcxx/vendor/llvm/default_assertion_handler.in b/libcxx/vendor/llvm/default_assertion_handler.in index d352405e905b5..f115658f9f3c6 100644 --- a/libcxx/vendor/llvm/default_assertion_handler.in +++ b/libcxx/vendor/llvm/default_assertion_handler.in @@ -16,7 +16,6 @@ # include <__cxx03/__verbose_trap> #else # include <__config> -# include <__log_hardening_failure> # include <__verbose_abort> # include <__verbose_trap> #endif @@ -25,40 +24,14 @@ # pragma GCC system_header #endif -#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG -// Keep the old implementation that doesn't support assertion semantics for backward compatibility with the frozen C++03 -// mode. -# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG -# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message) -# else -# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message) -# endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message) #else -# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE -# define _LIBCPP_ASSERTION_HANDLER(message) ((void)0) - -# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE -# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_HARDENING_FAILURE(message) - -# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE -# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message) - -# elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE -# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message) - -# else - -# error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \ -_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \ -_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \ -_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \ -_LIBCPP_ASSERTION_SEMANTIC_ENFORCE - -# endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE +# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_TRAP(message) -#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) +#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG #endif // _LIBCPP___ASSERTION_HANDLER diff --git a/libcxxabi/src/demangle/DemangleConfig.h b/libcxxabi/src/demangle/DemangleConfig.h index 7904e9d1eb133..06fd223f5553f 100644 --- a/libcxxabi/src/demangle/DemangleConfig.h +++ b/libcxxabi/src/demangle/DemangleConfig.h @@ -19,14 +19,6 @@ #include "../abort_message.h" #endif -#ifndef _LIBCPP_LOG_HARDENING_FAILURE -// Libc++abi does not have any functionality to log and continue, so we drop -// error messages when we build the demangler with `observe` assertion semantic. -// Once the layering with libc++ is improved, this could use the libc++ -// functionality to log hardening failures. -#define _LIBCPP_LOG_HARDENING_FAILURE(message) ((void)0) -#endif - #include #ifdef _MSC_VER