diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h --- a/libc/utils/MPFRWrapper/MPFRUtils.h +++ b/libc/utils/MPFRWrapper/MPFRUtils.h @@ -176,7 +176,7 @@ Operation op, const TernaryInput &input, T match_value, double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS); -template +template class MPFRMatcher : public testing::Matcher { InputType input; OutputType match_value; @@ -198,6 +198,11 @@ explain_error(input, match_value, OS); } + // Whether the `explainError` step is skipped or not. + bool is_silent() const override { + return silent; + } + private: template bool match(T in, T out) { return compare_unary_operation_single_output(op, in, out, ulp_tolerance, @@ -291,11 +296,23 @@ template __attribute__((no_sanitize("address"))) cpp::enable_if_t(), - internal::MPFRMatcher> + internal::MPFRMatcher> get_mpfr_matcher(InputType input, OutputType output_unused, double ulp_tolerance, RoundingMode rounding) { - return internal::MPFRMatcher(input, ulp_tolerance, - rounding); + return internal::MPFRMatcher( + input, ulp_tolerance, rounding); +} + +template +__attribute__((no_sanitize("address"))) +cpp::enable_if_t(), + internal::MPFRMatcher> +get_silent_mpfr_matcher(InputType input, OutputType output_unused, + double ulp_tolerance, RoundingMode rounding) { + return internal::MPFRMatcher( + input, ulp_tolerance, rounding); } template T round(T x, RoundingMode mode); @@ -346,6 +363,12 @@ mpfr::RoundingMode::TowardZero); \ } +#define EXPECT_MPFR_MATCH_ROUNDING_SILENTLY(op, input, match_value, \ + ulp_tolerance, rounding) \ + EXPECT_THAT(match_value, \ + __llvm_libc::testing::mpfr::get_silent_mpfr_matcher( \ + input, match_value, ulp_tolerance, rounding)) + #define ASSERT_MPFR_MATCH_DEFAULT(op, input, match_value, ulp_tolerance) \ ASSERT_THAT(match_value, \ __llvm_libc::testing::mpfr::get_mpfr_matcher( \ diff --git a/libc/utils/UnitTest/LibcTest.h b/libc/utils/UnitTest/LibcTest.h --- a/libc/utils/UnitTest/LibcTest.h +++ b/libc/utils/UnitTest/LibcTest.h @@ -53,6 +53,8 @@ virtual void explainError(testutils::StreamWrapper &OS) { OS << "unknown error\n"; } + // Override and return true to skip `explainError` step. + virtual bool is_silent() const { return false; } }; template struct Matcher : public MatcherBase { bool match(T &t); }; diff --git a/libc/utils/UnitTest/LibcTest.cpp b/libc/utils/UnitTest/LibcTest.cpp --- a/libc/utils/UnitTest/LibcTest.cpp +++ b/libc/utils/UnitTest/LibcTest.cpp @@ -310,10 +310,12 @@ return true; Ctx->markFail(); - std::cout << File << ":" << Line << ": FAILURE\n" - << "Failed to match " << LHSStr << " against " << RHSStr << ".\n"; - testutils::StreamWrapper OutsWrapper = testutils::outs(); - Matcher.explainError(OutsWrapper); + if (!Matcher.is_silent()) { + std::cout << File << ":" << Line << ": FAILURE\n" + << "Failed to match " << LHSStr << " against " << RHSStr << ".\n"; + testutils::StreamWrapper OutsWrapper = testutils::outs(); + Matcher.explainError(OutsWrapper); + } return false; }