Index: base/numerics/safe_math.h |
diff --git a/base/numerics/safe_math.h b/base/numerics/safe_math.h |
index 0c88a7c2a30d6efb4597007be46056eb1d2fc999..acdf682f0875258de21987fea4bfc04c3cda4efb 100644 |
--- a/base/numerics/safe_math.h |
+++ b/base/numerics/safe_math.h |
@@ -119,24 +119,18 @@ class CheckedNumeric { |
template <typename Src> CheckedNumeric& operator%=(Src rhs); |
CheckedNumeric operator-() const { |
- bool is_valid; |
- T value = CheckedNeg(state_.value(), &is_valid); |
// Negation is always valid for floating point. |
- if (std::numeric_limits<T>::is_iec559) |
- return CheckedNumeric<T>(value); |
- |
- is_valid &= state_.is_valid(); |
+ T value = 0; |
+ bool is_valid = (std::numeric_limits<T>::is_iec559 || IsValid()) && |
+ CheckedNeg(state_.value(), &value); |
return CheckedNumeric<T>(value, is_valid); |
} |
CheckedNumeric Abs() const { |
- bool is_valid; |
- T value = CheckedAbs(state_.value(), &is_valid); |
// Absolute value is always valid for floating point. |
- if (std::numeric_limits<T>::is_iec559) |
- return CheckedNumeric<T>(value); |
- |
- is_valid &= state_.is_valid(); |
+ T value = 0; |
+ bool is_valid = (std::numeric_limits<T>::is_iec559 || IsValid()) && |
+ CheckedAbs(state_.value(), &value); |
return CheckedNumeric<T>(value, is_valid); |
} |
@@ -145,7 +139,7 @@ class CheckedNumeric { |
// of the source, and properly handling signed min. |
CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const { |
return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>( |
- CheckedUnsignedAbs(state_.value()), state_.is_valid()); |
+ SafeUnsignedAbs(state_.value()), state_.is_valid()); |
} |
CheckedNumeric& operator++() { |
@@ -220,15 +214,16 @@ class CheckedNumeric { |
/* Floating point always takes the fast path */ \ |
if (std::numeric_limits<T>::is_iec559) \ |
return CheckedNumeric<T>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \ |
+ if (!rhs.IsValid() || !lhs.IsValid()) \ |
+ return CheckedNumeric<Promotion>(0, false); \ |
if (IsIntegerArithmeticSafe<Promotion, T, T>::value) \ |
- return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ |
- rhs.IsValid() && lhs.IsValid()); \ |
- bool is_valid = true; \ |
- T result = static_cast<T>( \ |
+ return CheckedNumeric<Promotion>(lhs.ValueUnsafe() \ |
+ OP rhs.ValueUnsafe()); \ |
+ Promotion result = 0; \ |
+ bool is_valid = \ |
Checked##NAME(static_cast<Promotion>(lhs.ValueUnsafe()), \ |
- static_cast<Promotion>(rhs.ValueUnsafe()), &is_valid)); \ |
- return CheckedNumeric<Promotion>( \ |
- result, is_valid && lhs.IsValid() && rhs.IsValid()); \ |
+ static_cast<Promotion>(rhs.ValueUnsafe()), &result); \ |
+ return CheckedNumeric<Promotion>(result, is_valid); \ |
} \ |
/* Assignment arithmetic operator implementation from CheckedNumeric. */ \ |
template <typename T> \ |
@@ -243,9 +238,10 @@ class CheckedNumeric { |
CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ |
const CheckedNumeric<Src>& lhs, const CheckedNumeric<T>& rhs) { \ |
typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ |
+ if (!rhs.IsValid() || !lhs.IsValid()) \ |
+ return CheckedNumeric<Promotion>(0, false); \ |
if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ |
- return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ |
- rhs.IsValid() && lhs.IsValid()); \ |
+ return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe());\ |
return CheckedNumeric<Promotion>::cast(lhs) \ |
OP CheckedNumeric<Promotion>::cast(rhs); \ |
} \ |