Commit c60c2e3e authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[base] Make DCHECK_EQ and other constexpr

This allows us to use them in constexpr contexts, just as DCHECK.
There were some "constexpr" keywords missing, and we cannot have
explicit template instantiations for constexpr.

R=jkummerow@chromium.org

Bug: v8:9810
Change-Id: Iba7c6ed4a16ea5077324880f59f7f0e17d1757a4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1910956Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64921}
parent ae4506e2
......@@ -106,21 +106,6 @@ DEFINE_MAKE_CHECK_OP_STRING(unsigned long long) // NOLINT(runtime/int)
DEFINE_MAKE_CHECK_OP_STRING(void const*)
#undef DEFINE_MAKE_CHECK_OP_STRING
// Explicit instantiations for floating point checks.
#define DEFINE_CHECK_OP_IMPL(NAME) \
template std::string* Check##NAME##Impl<float, float>(float lhs, float rhs, \
char const* msg); \
template std::string* Check##NAME##Impl<double, double>( \
double lhs, double rhs, char const* msg);
DEFINE_CHECK_OP_IMPL(EQ)
DEFINE_CHECK_OP_IMPL(NE)
DEFINE_CHECK_OP_IMPL(LE)
DEFINE_CHECK_OP_IMPL(LT)
DEFINE_CHECK_OP_IMPL(GE)
DEFINE_CHECK_OP_IMPL(GT)
#undef DEFINE_CHECK_OP_IMPL
} // namespace base
} // namespace v8
......
......@@ -198,7 +198,7 @@ DEFINE_PRINT_CHECK_OPERAND_CHAR(unsigned char)
// be out of line, while the "Impl" code should be inline. Caller
// takes ownership of the returned string.
template <typename Lhs, typename Rhs>
std::string* MakeCheckOpString(Lhs lhs, Rhs rhs, char const* msg) {
V8_NOINLINE std::string* MakeCheckOpString(Lhs lhs, Rhs rhs, char const* msg) {
std::ostringstream ss;
ss << msg << " (";
PrintCheckOperand<Lhs>(ss, lhs);
......@@ -268,11 +268,12 @@ struct is_unsigned_vs_signed : public is_signed_vs_unsigned<Rhs, Lhs> {};
#define MAKE_UNSIGNED(Type, value) \
static_cast<typename std::make_unsigned< \
typename comparison_underlying_type<Type>::type>::type>(value)
#define DEFINE_SIGNED_MISMATCH_COMP(CHECK, NAME, IMPL) \
template <typename Lhs, typename Rhs> \
V8_INLINE typename std::enable_if<CHECK<Lhs, Rhs>::value, bool>::type \
Cmp##NAME##Impl(Lhs lhs, Rhs rhs) { \
return IMPL; \
#define DEFINE_SIGNED_MISMATCH_COMP(CHECK, NAME, IMPL) \
template <typename Lhs, typename Rhs> \
V8_INLINE constexpr \
typename std::enable_if<CHECK<Lhs, Rhs>::value, bool>::type \
Cmp##NAME##Impl(Lhs lhs, Rhs rhs) { \
return IMPL; \
}
DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, EQ,
lhs >= 0 && MAKE_UNSIGNED(Lhs, lhs) ==
......@@ -302,29 +303,24 @@ DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, GE, CmpLEImpl(rhs, lhs))
// not integral or their signedness matches (i.e. whenever no specialization is
// required, see above). Otherwise it is disabled by the enable_if construct,
// and the compiler will pick a specialization from above.
#define DEFINE_CHECK_OP_IMPL(NAME, op) \
template <typename Lhs, typename Rhs> \
V8_INLINE \
typename std::enable_if<!is_signed_vs_unsigned<Lhs, Rhs>::value && \
!is_unsigned_vs_signed<Lhs, Rhs>::value, \
bool>::type Cmp##NAME##Impl(Lhs lhs, Rhs rhs) { \
return lhs op rhs; \
} \
template <typename Lhs, typename Rhs> \
V8_INLINE std::string* Check##NAME##Impl(Lhs lhs, Rhs rhs, \
char const* msg) { \
using LhsPassT = typename pass_value_or_ref<Lhs>::type; \
using RhsPassT = typename pass_value_or_ref<Rhs>::type; \
bool cmp = Cmp##NAME##Impl<LhsPassT, RhsPassT>(lhs, rhs); \
return V8_LIKELY(cmp) \
? nullptr \
: MakeCheckOpString<LhsPassT, RhsPassT>(lhs, rhs, msg); \
} \
extern template V8_BASE_EXPORT std::string* Check##NAME##Impl<float, float>( \
float lhs, float rhs, char const* msg); \
extern template V8_BASE_EXPORT std::string* \
Check##NAME##Impl<double, double>(double lhs, double rhs, \
char const* msg);
#define DEFINE_CHECK_OP_IMPL(NAME, op) \
template <typename Lhs, typename Rhs> \
V8_INLINE constexpr \
typename std::enable_if<!is_signed_vs_unsigned<Lhs, Rhs>::value && \
!is_unsigned_vs_signed<Lhs, Rhs>::value, \
bool>::type Cmp##NAME##Impl(Lhs lhs, Rhs rhs) { \
return lhs op rhs; \
} \
template <typename Lhs, typename Rhs> \
V8_INLINE constexpr std::string* Check##NAME##Impl(Lhs lhs, Rhs rhs, \
char const* msg) { \
using LhsPassT = typename pass_value_or_ref<Lhs>::type; \
using RhsPassT = typename pass_value_or_ref<Rhs>::type; \
bool cmp = Cmp##NAME##Impl<LhsPassT, RhsPassT>(lhs, rhs); \
return V8_LIKELY(cmp) \
? nullptr \
: MakeCheckOpString<LhsPassT, RhsPassT>(lhs, rhs, msg); \
}
DEFINE_CHECK_OP_IMPL(EQ, ==)
DEFINE_CHECK_OP_IMPL(NE, !=)
DEFINE_CHECK_OP_IMPL(LE, <=)
......
......@@ -31,7 +31,7 @@ template <InstanceType upper_limit>
struct InstanceRangeChecker<FIRST_TYPE, upper_limit> {
static constexpr bool Check(InstanceType value) {
#if V8_HAS_CXX14_CONSTEXPR
DCHECK(value >= FIRST_TYPE);
DCHECK_LE(FIRST_TYPE, value);
#endif
return value <= upper_limit;
}
......@@ -40,7 +40,7 @@ template <InstanceType lower_limit>
struct InstanceRangeChecker<lower_limit, LAST_TYPE> {
static constexpr bool Check(InstanceType value) {
#if V8_HAS_CXX14_CONSTEXPR
DCHECK(value <= LAST_TYPE);
DCHECK_GE(LAST_TYPE, value);
#endif
return value >= lower_limit;
}
......
......@@ -41,8 +41,7 @@ class InternalIndex {
}
constexpr int as_int() const {
#if V8_HAS_CXX14_CONSTEXPR
// TODO(clemensb): DCHECK_LE is not constexpr.
DCHECK(entry_ <= std::numeric_limits<int>::max());
DCHECK_LE(entry_, std::numeric_limits<int>::max());
#endif
return static_cast<int>(entry_);
}
......
......@@ -74,8 +74,8 @@ class Smi : public Object {
// Returns whether value can be represented in a Smi.
static inline bool constexpr IsValid(intptr_t value) {
#if V8_HAS_CXX14_CONSTEXPR
DCHECK(Internals::IsValidSmi(value) ==
(value >= kMinValue && value <= kMaxValue));
DCHECK_EQ(Internals::IsValidSmi(value),
value >= kMinValue && value <= kMaxValue);
#endif
return Internals::IsValidSmi(value);
}
......
......@@ -58,7 +58,7 @@ inline char HexCharOfValue(int value) {
template <typename T, typename U>
inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) {
#if V8_HAS_CXX14_CONSTEXPR
DCHECK(lower_limit <= higher_limit);
DCHECK_LE(lower_limit, higher_limit);
#endif
STATIC_ASSERT(sizeof(U) <= sizeof(T));
using unsigned_T = typename std::make_unsigned<T>::type;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment