| Index: base/numerics/checked_math_impl.h
 | 
| diff --git a/base/numerics/checked_math_impl.h b/base/numerics/checked_math_impl.h
 | 
| index 0492d1dbb5540e4f7a90a51bf4217a0a07388b27..bf3a3077efb75341285c7a480f757839238f8d83 100644
 | 
| --- a/base/numerics/checked_math_impl.h
 | 
| +++ b/base/numerics/checked_math_impl.h
 | 
| @@ -182,17 +182,19 @@ struct CheckedMulOp<T,
 | 
|        return !__builtin_mul_overflow(x, y, result);
 | 
|  #endif
 | 
|      using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type;
 | 
| +    // Verify the destination type can hold the result (always true for 0).
 | 
| +    if (!(IsValueInRangeForNumericType<Promotion>(x) &&
 | 
| +          IsValueInRangeForNumericType<Promotion>(y)) &&
 | 
| +        x && y) {
 | 
| +      return false;
 | 
| +    }
 | 
|      Promotion presult;
 | 
| -    // Fail if either operand is out of range for the promoted type.
 | 
| -    // TODO(jschuh): This could be made to work for a broader range of values.
 | 
| -    bool is_valid = IsValueInRangeForNumericType<Promotion>(x) &&
 | 
| -                    IsValueInRangeForNumericType<Promotion>(y);
 | 
| -
 | 
| +    bool is_valid = true;
 | 
|      if (IsIntegerArithmeticSafe<Promotion, T, U>::value) {
 | 
|        presult = static_cast<Promotion>(x) * static_cast<Promotion>(y);
 | 
|      } else {
 | 
| -      is_valid &= CheckedMulImpl(static_cast<Promotion>(x),
 | 
| -                                 static_cast<Promotion>(y), &presult);
 | 
| +      is_valid = CheckedMulImpl(static_cast<Promotion>(x),
 | 
| +                                static_cast<Promotion>(y), &presult);
 | 
|      }
 | 
|      *result = static_cast<V>(presult);
 | 
|      return is_valid && IsValueInRangeForNumericType<V>(presult);
 | 
| @@ -242,7 +244,7 @@ struct CheckedDivOp<T,
 | 
|  template <typename T>
 | 
|  bool CheckedModImpl(T x, T y, T* result) {
 | 
|    static_assert(std::is_integral<T>::value, "Type must be integral");
 | 
| -  if (y > 0) {
 | 
| +  if (y) {
 | 
|      *result = static_cast<T>(x % y);
 | 
|      return true;
 | 
|    }
 | 
| @@ -283,15 +285,15 @@ struct CheckedLshOp<T,
 | 
|    using result_type = T;
 | 
|    template <typename V>
 | 
|    static bool Do(T x, U shift, V* result) {
 | 
| -    using ShiftType = typename std::make_unsigned<T>::type;
 | 
| -    static const ShiftType kBitWidth = IntegerBitsPlusSign<T>::value;
 | 
| -    const ShiftType real_shift = static_cast<ShiftType>(shift);
 | 
|      // Signed shift is not legal on negative values.
 | 
| -    if (!IsValueNegative(x) && real_shift < kBitWidth) {
 | 
| +    if (!IsValueNegative(x) &&
 | 
| +        as_unsigned(shift) < IntegerBitsPlusSign<T>::value) {
 | 
|        // Just use a multiplication because it's easy.
 | 
|        // TODO(jschuh): This could probably be made more efficient.
 | 
| -      if (!std::is_signed<T>::value || real_shift != kBitWidth - 1)
 | 
| -        return CheckedMulOp<T, T>::Do(x, static_cast<T>(1) << shift, result);
 | 
| +      if (!std::is_signed<T>::value ||
 | 
| +          as_unsigned(shift) < std::numeric_limits<T>::digits)
 | 
| +        return CheckedMulOp<T, T>::Do(x, T(1) << shift, result);
 | 
| +      *result = 0;
 | 
|        return !x;  // Special case zero for a full width signed shift.
 | 
|      }
 | 
|      return false;
 | 
| @@ -313,8 +315,7 @@ struct CheckedRshOp<T,
 | 
|    template <typename V>
 | 
|    static bool Do(T x, U shift, V* result) {
 | 
|      // Use the type conversion push negative values out of range.
 | 
| -    using ShiftType = typename std::make_unsigned<T>::type;
 | 
| -    if (static_cast<ShiftType>(shift) < IntegerBitsPlusSign<T>::value) {
 | 
| +    if (as_unsigned(shift) < IntegerBitsPlusSign<T>::value) {
 | 
|        T tmp = x >> shift;
 | 
|        *result = static_cast<V>(tmp);
 | 
|        return IsValueInRangeForNumericType<V>(tmp);
 | 
| 
 |