brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 9d356ef Raw
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