When printing CHECK_XX failures and both types are unprintable, don't bother printing " (UNPRINTABLE vs. UNPRINTABLE)".
PiperOrigin-RevId: 802287138
Change-Id: I8b4815fdc089427be9f276e10f9a72b398ed8f80
diff --git a/absl/log/check_test_impl.inc b/absl/log/check_test_impl.inc
index 7bcedd4..495f85a 100644
--- a/absl/log/check_test_impl.inc
+++ b/absl/log/check_test_impl.inc
@@ -292,8 +292,7 @@
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 5db98dd..be8ceaf 100644
--- a/absl/log/internal/check_op.cc
+++ b/absl/log/internal/check_op.cc
@@ -101,7 +101,9 @@
}
}
-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 c607864..4d0842b 100644
--- a/absl/log/internal/check_op.h
+++ b/absl/log/internal/check_op.h
@@ -225,17 +225,12 @@
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 @@
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