Index: base/numerics/safe_math_impl.h |
diff --git a/base/numerics/safe_math_impl.h b/base/numerics/safe_math_impl.h |
index 65589baadb26a4e0d8382cc2cf59af10063a9e3a..9a47a27a08139ba01c4f8794ab7e3a0194f9e961 100644 |
--- a/base/numerics/safe_math_impl.h |
+++ b/base/numerics/safe_math_impl.h |
@@ -57,6 +57,7 @@ bool CheckedAddImpl(T x, T y, T* result) { |
// Since the value of x+y is undefined if we have a signed type, we compute |
// it using the unsigned type of the same size. |
using UnsignedDst = typename std::make_unsigned<T>::type; |
+ using SignedDst = typename std::make_signed<T>::type; |
UnsignedDst ux = static_cast<UnsignedDst>(x); |
UnsignedDst uy = static_cast<UnsignedDst>(y); |
UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy); |
@@ -64,10 +65,8 @@ bool CheckedAddImpl(T x, T y, T* result) { |
// Addition is valid if the sign of (x + y) is equal to either that of x or |
// that of y. |
return (std::is_signed<T>::value) |
- ? HasSignBit(BinaryComplement( |
- static_cast<UnsignedDst>((uresult ^ ux) & (uresult ^ uy)))) |
- : (BinaryComplement(x) >= |
- y); // Unsigned is either valid or underflow. |
+ ? static_cast<SignedDst>((uresult ^ ux) & (uresult ^ uy)) >= 0 |
+ : uresult >= uy; // Unsigned is either valid or underflow. |
} |
template <typename T, typename U, class Enable = void> |
@@ -109,6 +108,7 @@ bool CheckedSubImpl(T x, T y, T* result) { |
// Since the value of x+y is undefined if we have a signed type, we compute |
// it using the unsigned type of the same size. |
using UnsignedDst = typename std::make_unsigned<T>::type; |
+ using SignedDst = typename std::make_signed<T>::type; |
UnsignedDst ux = static_cast<UnsignedDst>(x); |
UnsignedDst uy = static_cast<UnsignedDst>(y); |
UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy); |
@@ -116,9 +116,8 @@ bool CheckedSubImpl(T x, T y, T* result) { |
// Subtraction is valid if either x and y have same sign, or (x-y) and x have |
// the same sign. |
return (std::is_signed<T>::value) |
- ? HasSignBit(BinaryComplement( |
- static_cast<UnsignedDst>((uresult ^ ux) & (ux ^ uy)))) |
- : (x >= y); |
+ ? static_cast<SignedDst>((uresult ^ ux) & (ux ^ uy)) >= 0 |
+ : x >= y; |
} |
template <typename T, typename U, class Enable = void> |
@@ -180,11 +179,11 @@ bool CheckedMulImpl(T x, T y, T* result) { |
// Since the value of x*y is potentially undefined if we have a signed type, |
// we compute it using the unsigned type of the same size. |
using UnsignedDst = typename std::make_unsigned<T>::type; |
- const T is_negative = HasSignBit(x) ^ HasSignBit(y); |
const UnsignedDst ux = SafeUnsignedAbs(x); |
const UnsignedDst uy = SafeUnsignedAbs(y); |
UnsignedDst uresult = static_cast<UnsignedDst>(ux * uy); |
// This is a non-branching conditional negation. |
+ const T is_negative = (x ^ y) < 0; |
*result = static_cast<T>((uresult ^ -is_negative) + is_negative); |
// This uses the unsigned overflow check on the absolute value, with a +1 |
// bound for a negative result. |