Add (D)CHECK_IMPLIES to ART logging
Adds an _IMPLIES macro which is equivalent to checking a => b. This
CL includes an example of how it could be useful to aid
readability.
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: If36ccf2a1d10ebd0b0c9f9635020dc78f5ae94ae
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 1016652..ff4ab59 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -5195,8 +5195,7 @@
if (byte_swap) {
v = BSWAP(v);
}
- // `field_type == DataType::Type::kReference` implies `v == 0`.
- DCHECK((field_type != DataType::Type::kReference) || (v == 0));
+ DCHECK_IMPLIES(field_type == DataType::Type::kReference, v == 0);
// Note: if heap poisoning is enabled, no need to poison
// (negate) `v` if it is a reference, as it would be null.
__ movl(field_addr, Immediate(v));
diff --git a/libartbase/base/logging.h b/libartbase/base/logging.h
index e573f03..7a421a4 100644
--- a/libartbase/base/logging.h
+++ b/libartbase/base/logging.h
@@ -149,6 +149,24 @@
-1) \
.stream()
+// Check whether an implication holds between x and y, LOG(FATAL) if not. The value
+// of the expressions x and y is evaluated once. Extra logging can be appended
+// using << after. For example:
+//
+// CHECK_IMPLIES(1==1, 0==1) results in
+// "Check failed: 1==1 (true) implies 0==1 (false) ".
+// clang-format off
+#define CHECK_IMPLIES(LHS, RHS) \
+ LIKELY(!(LHS) || (RHS)) || ABORT_AFTER_LOG_FATAL_EXPR(false) || \
+ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, _LOG_TAG_INTERNAL, \
+ -1) \
+ .stream() \
+ << "Check failed: " #LHS << " (true) implies " #RHS << " (false)"
+// clang-format on
+
+#define DCHECK_IMPLIES(a, b) \
+ if (::android::base::kEnableDChecks) CHECK_IMPLIES(a, b)
+
} // namespace art
#endif // ART_LIBARTBASE_BASE_LOGGING_H_