From 79bdf3b41f01fe488dd2d82a2c6260cfbca544c4 Mon Sep 17 00:00:00 2001 From: Andy Getzendanner Date: Tue, 2 Sep 2025 14:13:13 -0700 Subject: [PATCH] When printing CHECK_XX failures and both types are unprintable, don't bother printing " (UNPRINTABLE vs. UNPRINTABLE)". PiperOrigin-RevId: 802287138 Change-Id: I8b4815fdc089427be9f276e10f9a72b398ed8f80 --- absl/log/check_test_impl.inc | 3 +-- absl/log/internal/check_op.cc | 4 +++- absl/log/internal/check_op.h | 21 +++++++++++---------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/absl/log/check_test_impl.inc b/absl/log/check_test_impl.inc index 7bcedd40..495f85a2 100644 --- a/absl/log/check_test_impl.inc +++ b/absl/log/check_test_impl.inc @@ -292,8 +292,7 @@ TEST(CHECKDeathTest, TestBinaryChecksWithUnprintable) { ExampleTypeThatHasNoStreamOperator a{true}; ExampleTypeThatHasNoStreamOperator b{false}; ABSL_TEST_CHECK_EQ(a, a); - EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), - "Check failed: a == b \\(UNPRINTABLE vs. UNPRINTABLE\\)"); + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), "Check failed: a == b"); ABSL_TEST_CHECK_EQ(a, true); EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, false), "Check failed: a == false \\(UNPRINTABLE vs. 0\\)"); diff --git a/absl/log/internal/check_op.cc b/absl/log/internal/check_op.cc index 5db98dd9..be8ceaf4 100644 --- a/absl/log/internal/check_op.cc +++ b/absl/log/internal/check_op.cc @@ -101,7 +101,9 @@ void MakeCheckOpValueString(std::ostream& os, const void* p) { } } -void MakeCheckOpUnprintableString(std::ostream& os) { os << "UNPRINTABLE"; } +std::ostream& operator<<(std::ostream& os, UnprintableWrapper) { + return os << "UNPRINTABLE"; +} // Helper functions for string comparisons. #define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ diff --git a/absl/log/internal/check_op.h b/absl/log/internal/check_op.h index c6078640..4d0842bc 100644 --- a/absl/log/internal/check_op.h +++ b/absl/log/internal/check_op.h @@ -225,17 +225,12 @@ void MakeCheckOpValueString(std::ostream& os, signed char v); void MakeCheckOpValueString(std::ostream& os, unsigned char v); void MakeCheckOpValueString(std::ostream& os, const void* absl_nullable p); -void MakeCheckOpUnprintableString(std::ostream& os); - // A wrapper for types that have no operator<<. struct UnprintableWrapper { template explicit UnprintableWrapper(const T&) {} - friend std::ostream& operator<<(std::ostream& os, const UnprintableWrapper&) { - MakeCheckOpUnprintableString(os); - return os; - } + friend std::ostream& operator<<(std::ostream& os, UnprintableWrapper); }; namespace detect_specialization { @@ -400,10 +395,16 @@ ABSL_ATTRIBUTE_RETURNS_NONNULL const char* absl_nonnull MakeCheckOpString( template const char* absl_nonnull MakeCheckOpString(T1 v1, T2 v2, const char* absl_nonnull exprtext) { - CheckOpMessageBuilder comb(exprtext); - MakeCheckOpValueString(comb.ForVar1(), v1); - MakeCheckOpValueString(comb.ForVar2(), v2); - return comb.NewString(); + if constexpr (std::is_same_v, UnprintableWrapper> && + std::is_same_v, UnprintableWrapper>) { + // No sense printing " (UNPRINTABLE vs. UNPRINTABLE)" + return exprtext; + } else { + CheckOpMessageBuilder comb(exprtext); + MakeCheckOpValueString(comb.ForVar1(), v1); + MakeCheckOpValueString(comb.ForVar2(), v2); + return comb.NewString(); + } } // Add a few commonly used instantiations as extern to reduce size of objects