Commit 38b586c6 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[base] Fix CHECK/DCHECK macros for enum types

The problem with enums is that neither is_integral, nor is_signed or
is_unsigned is true for them. Thus, comparison with our CHECK/DCHECK
macros always just uses the default comparison, which fails if the
signedness of the underlying integer types does not match.
This CL fixes this by considering the underlying integer type of an
enum to choose the right comparison operator.

R=ishell@chromium.org
CC=ahaas@chromium.org

Change-Id: I5ef56d1b86228e879f5866967ab7e709f1e97f0b
Reviewed-on: https://chromium-review.googlesource.com/518123
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45593}
parent 8820a79e
......@@ -141,16 +141,30 @@ DEFINE_MAKE_CHECK_OP_STRING(char const*)
DEFINE_MAKE_CHECK_OP_STRING(void const*)
#undef DEFINE_MAKE_CHECK_OP_STRING
// comparison_underlying_type provides the underlying integral type of an enum,
// or std::decay<T>::type if T is not an enum.
template <typename T>
struct comparison_underlying_type {
// std::underlying_type must only be used with enum types, thus use this
// {Dummy} type if the given type is not an enum.
enum Dummy {};
using decay = typename std::decay<T>::type;
static constexpr bool is_enum = std::is_enum<decay>::value;
using underlying = typename std::underlying_type<
typename std::conditional<is_enum, decay, Dummy>::type>::type;
using type = typename std::conditional<is_enum, underlying, decay>::type;
};
// is_signed_vs_unsigned::value is true if both types are integral, Lhs is
// signed, and Rhs is unsigned. False in all other cases.
template <typename Lhs, typename Rhs>
struct is_signed_vs_unsigned {
enum : bool {
value = std::is_integral<typename std::decay<Lhs>::type>::value &&
std::is_integral<typename std::decay<Rhs>::type>::value &&
std::is_signed<typename std::decay<Lhs>::type>::value &&
std::is_unsigned<typename std::decay<Rhs>::type>::value
};
using lhs_underlying = typename comparison_underlying_type<Lhs>::type;
using rhs_underlying = typename comparison_underlying_type<Rhs>::type;
static constexpr bool value = std::is_integral<lhs_underlying>::value &&
std::is_integral<rhs_underlying>::value &&
std::is_signed<lhs_underlying>::value &&
std::is_unsigned<rhs_underlying>::value;
};
// Same thing, other way around: Lhs is unsigned, Rhs signed.
template <typename Lhs, typename Rhs>
......@@ -159,10 +173,9 @@ struct is_unsigned_vs_signed : public is_signed_vs_unsigned<Rhs, Lhs> {};
// Specialize the compare functions for signed vs. unsigned comparisons.
// std::enable_if ensures that this template is only instantiable if both Lhs
// and Rhs are integral types, and their signedness does not match.
#define MAKE_UNSIGNED(Type, value) \
static_cast< \
typename std::make_unsigned<typename std::decay<Type>::type>::type>( \
value)
#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 \
......
......@@ -393,14 +393,14 @@ FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
return const_cast<FunctionSig*>(
kSimpleExprSigs[kSimdExprSigTable[opcode & 0xff]]);
} else {
DCHECK_GT(kSimpleExprSigTable.size(), static_cast<size_t>(opcode));
DCHECK_GT(kSimpleExprSigTable.size(), opcode);
return const_cast<FunctionSig*>(
kSimpleExprSigs[kSimpleExprSigTable[opcode]]);
}
}
FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
DCHECK_GT(kSimpleAsmjsExprSigTable.size(), static_cast<size_t>(opcode));
DCHECK_GT(kSimpleAsmjsExprSigTable.size(), opcode);
return const_cast<FunctionSig*>(
kSimpleExprSigs[kSimpleAsmjsExprSigTable[opcode]]);
}
......
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