When printing CHECK_XX failures and both types are unprintable, don't bother printing " (UNPRINTABLE vs. UNPRINTABLE)".

PiperOrigin-RevId: 802287138
Change-Id: I8b4815fdc089427be9f276e10f9a72b398ed8f80
This commit is contained in:
Andy Getzendanner
2025-09-02 14:13:13 -07:00
committed by Copybara-Service
parent 4dd0ffdf2a
commit 79bdf3b41f
3 changed files with 15 additions and 13 deletions

View File

@@ -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\\)");

View File

@@ -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) \

View File

@@ -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 <typename T>
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 <typename T1, typename T2>
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<CheckOpStreamType<T1>, UnprintableWrapper> &&
std::is_same_v<CheckOpStreamType<T2>, 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