141 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: has-unix-headers10// UNSUPPORTED: c++0311// UNSUPPORTED: libcpp-hardening-mode=none12// XFAIL: availability-verbose_abort-missing13 14#include <cassert>15#include <cstdio>16#include <string>17 18#include "check_assertion.h"19 20template <class Func>21bool TestDeathTest(22 Outcome expected_outcome, DeathCause expected_cause, const char* stmt, Func&& func, const Matcher& matcher) {23 auto get_matcher = [&] {24#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE25 (void)matcher;26 return MakeAnyMatcher();27#else28 return matcher;29#endif30 };31 32 DeathTest test_case;33 DeathTestResult test_result = test_case.Run(std::array<DeathCause, 1>{expected_cause}, func, get_matcher());34 std::string maybe_failure_description;35 36 Outcome outcome = test_result.outcome();37 if (expected_outcome != outcome) {38 maybe_failure_description +=39 std::string("Test outcome was different from expected; expected ") + ToString(expected_outcome) +40 ", got: " + ToString(outcome);41 }42 43 DeathCause cause = test_result.cause();44 if (expected_cause != cause) {45 auto failure_description =46 std::string("Cause of death was different from expected; expected ") + ToString(expected_cause) +47 ", got: " + ToString(cause);48 if (maybe_failure_description.empty()) {49 maybe_failure_description = failure_description;50 } else {51 maybe_failure_description += std::string("; ") + failure_description;52 }53 }54 55 if (!maybe_failure_description.empty()) {56 test_case.PrintFailureDetails("EXPECT_DEATH", maybe_failure_description, stmt, test_result.cause());57 return false;58 }59 60 return true;61}62 63// clang-format off64 65#define TEST_DEATH_TEST(outcome, cause, ...) \66 assert(( TestDeathTest(outcome, cause, #__VA_ARGS__, [&]() { __VA_ARGS__; }, MakeAnyMatcher()) ))67#define TEST_DEATH_TEST_MATCHES(outcome, cause, matcher, ...) \68 assert(( TestDeathTest(outcome, cause, #__VA_ARGS__, [&]() { __VA_ARGS__; }, matcher) ))69 70// clang-format on71 72#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE73DeathCause assertion_death_cause = DeathCause::VerboseAbort;74#else75DeathCause assertion_death_cause = DeathCause::Trap;76#endif77 78int main(int, char**) {79 [[maybe_unused]] auto fail_assert = [] { _LIBCPP_ASSERT(false, "Some message"); };80 Matcher good_matcher = MakeAssertionMessageMatcher("Some message");81 Matcher bad_matcher = MakeAssertionMessageMatcher("Bad expected message");82 83 // Test the implementation of death tests. We're bypassing the assertions added by the actual `EXPECT_DEATH` macros84 // which allows us to test failure cases (where the assertion would fail) as well.85 {86 // Success -- `std::terminate`.87 TEST_DEATH_TEST(Outcome::Success, DeathCause::StdTerminate, std::terminate());88 89 // Success -- trapping.90 TEST_DEATH_TEST(Outcome::Success, DeathCause::Trap, __builtin_trap());91 92 // `_LIBCPP_ASSERT` does not terminate the program if the `observe` semantic is used, so these tests would fail with93 // `DidNotDie` cause.94#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE95 96 // Success -- assertion failure with any matcher.97 TEST_DEATH_TEST_MATCHES(Outcome::Success, assertion_death_cause, MakeAnyMatcher(), fail_assert());98 99 // Success -- assertion failure with a specific matcher.100 TEST_DEATH_TEST_MATCHES(Outcome::Success, assertion_death_cause, good_matcher, fail_assert());101 102# if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE103 // Failure -- error message doesn't match.104 TEST_DEATH_TEST_MATCHES(Outcome::UnexpectedErrorMessage, assertion_death_cause, bad_matcher, fail_assert());105# endif106 107#endif // _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE108 109 // Invalid cause -- child did not die.110 TEST_DEATH_TEST(Outcome::InvalidCause, DeathCause::DidNotDie, ((void)0));111 112 // Invalid cause -- unknown.113 TEST_DEATH_TEST(Outcome::InvalidCause, DeathCause::Unknown, std::exit(13));114 }115 116 // Test the `EXPECT_DEATH` macros themselves. Since they assert success, we can only test successful cases.117 {118 auto invoke_verbose_abort = [] { _LIBCPP_VERBOSE_ABORT("contains some message"); };119 auto invoke_abort = [] { std::abort(); };120 121 auto simple_matcher = [](const std::string& text) {122 bool success = text.find("some") != std::string::npos;123 return MatchResult(success, "");124 };125 126 EXPECT_ANY_DEATH(_LIBCPP_VERBOSE_ABORT(""));127 EXPECT_ANY_DEATH(std::abort());128 EXPECT_ANY_DEATH(std::terminate());129 EXPECT_DEATH(invoke_verbose_abort());130 EXPECT_DEATH_MATCHES(MakeAnyMatcher(), invoke_verbose_abort());131 EXPECT_DEATH_MATCHES(simple_matcher, invoke_verbose_abort());132 EXPECT_STD_ABORT(invoke_abort());133 EXPECT_STD_TERMINATE([] { std::terminate(); });134#if _LIBCPP_ASSERTION_SEMANTIC != _LIBCPP_ASSERTION_SEMANTIC_OBSERVE135 TEST_LIBCPP_ASSERT_FAILURE(fail_assert(), "Some message");136#endif137 }138 139 return 0;140}141