llvm-project/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/pstl.exception_handling.pass.cpp
Konstantin Varlamov 8dfc67d672
[libc++][hardening] Rework how the assertion handler can be overridden. (#77883)
Previously there were two ways to override the verbose abort function
which gets called when a hardening assertion is triggered:
- compile-time: define the `_LIBCPP_VERBOSE_ABORT` macro;
- link-time: provide a definition of `__libcpp_verbose_abort` function.

This patch adds a new configure-time approach: the vendor can provide
a path to a custom header file which will get copied into the build by
CMake and included by the library. The header must provide a definition
of the
`_LIBCPP_ASSERTION_HANDLER` macro which is what will get called should
a hardening assertion fail. As of this patch, overriding
`_LIBCPP_VERBOSE_ABORT` will still work, but the previous mechanisms
will be effectively removed in a follow-up patch, making the
configure-time mechanism the sole way of overriding the default handler.

Note that `_LIBCPP_ASSERTION_HANDLER` only gets invoked when a hardening
assertion fails. It does not affect other cases where
`_LIBCPP_VERBOSE_ABORT` is currently used (e.g. when an exception is
thrown in the `-fno-exceptions` mode).

The library provides a default version of the custom header file that
will get used if it's not overridden by the vendor. That allows us to
always test the override mechanism and reduces the difference in
configuration between the pristine version of the library and
a platform-specific version.
2024-01-17 18:56:07 -08:00

88 lines
2.8 KiB
C++

//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: no-exceptions
// `check_assertion.h` requires Unix headers and regex support.
// UNSUPPORTED: !has-unix-headers, no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-pstl
// check that std::find(ExecutionPolicy), std::find_if(ExecutionPolicy) and std::find_if_not(ExecutionPolicy) terminate
// on user-thrown exceptions
#include <algorithm>
#include "check_assertion.h"
#include "test_execution_policies.h"
#include "test_iterators.h"
struct ThrowOnCompare {};
#ifndef TEST_HAS_NO_EXCEPTIONS
bool operator==(ThrowOnCompare, ThrowOnCompare) { throw int{}; }
#endif
int main(int, char**) {
test_execution_policies([](auto&& policy) {
// std::find
EXPECT_STD_TERMINATE([&] {
ThrowOnCompare a[2] = {};
(void)std::find(policy, std::begin(a), std::end(a), ThrowOnCompare{});
});
EXPECT_STD_TERMINATE([&] {
try {
int a[] = {1, 2};
(void)std::find(
policy, util::throw_on_move_iterator(std::begin(a), 1), util::throw_on_move_iterator(std::end(a), 1), 0);
} catch (const util::iterator_error&) {
assert(false);
}
std::terminate(); // make the test pass in case the algorithm didn't move the iterator
});
// std::find_if
EXPECT_STD_TERMINATE([&] {
int a[] = {1, 2};
(void)std::find_if(policy, std::begin(a), std::end(a), [](int) -> bool { throw int{}; });
});
EXPECT_STD_TERMINATE([&] {
try {
int a[] = {1, 2};
(void)std::find_if(
policy,
util::throw_on_move_iterator(std::begin(a), 1),
util::throw_on_move_iterator(std::end(a), 1),
[](int) { return true; });
} catch (const util::iterator_error&) {
assert(false);
}
std::terminate(); // make the test pass in case the algorithm didn't move the iterator
});
// std::find_if_not
EXPECT_STD_TERMINATE([&] {
int a[] = {1, 2};
(void)std::find_if_not(policy, std::begin(a), std::end(a), [](int) -> bool { throw int{}; });
});
EXPECT_STD_TERMINATE([&] {
try {
int a[] = {1, 2};
(void)std::find_if_not(
policy,
util::throw_on_move_iterator(std::begin(a), 1),
util::throw_on_move_iterator(std::end(a), 1),
[](int) { return true; });
} catch (const util::iterator_error&) {
assert(false);
}
std::terminate(); // make the test pass in case the algorithm didn't move the iterator
});
});
}