Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2189)

Unified Diff: base/numerics/safe_math_impl.h

Issue 2318713004: Fix undefined behavior in base/numerics (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/numerics/safe_math_impl.h
diff --git a/base/numerics/safe_math_impl.h b/base/numerics/safe_math_impl.h
index 77a9b0ba3c8b0395da0a630efc137a640fc73856..94ae89494d428a294a3729e6c307669bc3b98cb2 100644
--- a/base/numerics/safe_math_impl.h
+++ b/base/numerics/safe_math_impl.h
@@ -223,7 +223,7 @@ CheckedMul(T x, T y, RangeConstraint* validity) {
y >= std::numeric_limits<T>::max() / x ? RANGE_VALID : RANGE_OVERFLOW;
}
- return static_cast<T>(x * y);
+ return static_cast<T>(*validity == RANGE_VALID ? x * y : 0);
}
template <typename T>
@@ -235,7 +235,7 @@ CheckedMul(T x, T y, RangeConstraint* validity) {
*validity = (y == 0 || x <= std::numeric_limits<T>::max() / y)
? RANGE_VALID
: RANGE_OVERFLOW;
- return static_cast<T>(x * y);
+ return static_cast<T>(*validity == RANGE_VALID ? x * y : 0);
}
// Division just requires a check for an invalid negation on signed min/-1.
@@ -261,7 +261,7 @@ typename std::enable_if<std::numeric_limits<T>::is_integer &&
T>::type
CheckedMod(T x, T y, RangeConstraint* validity) {
*validity = y > 0 ? RANGE_VALID : RANGE_INVALID;
- return static_cast<T>(x % y);
+ return static_cast<T>(*validity == RANGE_VALID ? x % y: 0);
}
template <typename T>
@@ -281,7 +281,7 @@ CheckedNeg(T value, RangeConstraint* validity) {
*validity =
value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
// The negation of signed min is min, so catch that one.
- return static_cast<T>(-value);
+ return static_cast<T>(*validity == RANGE_VALID ? -value : 0);
}
template <typename T>
@@ -291,8 +291,8 @@ typename std::enable_if<std::numeric_limits<T>::is_integer &&
CheckedNeg(T value, RangeConstraint* validity) {
// The only legal unsigned negation is zero.
*validity = value ? RANGE_UNDERFLOW : RANGE_VALID;
- return static_cast<T>(
- -static_cast<typename SignedIntegerForSize<T>::type>(value));
+ return static_cast<T>(*validity == RANGE_VALID ?
+ -static_cast<typename SignedIntegerForSize<T>::type>(value) : 0);
}
template <typename T>
@@ -302,7 +302,7 @@ typename std::enable_if<std::numeric_limits<T>::is_integer &&
CheckedAbs(T value, RangeConstraint* validity) {
*validity =
value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
- return static_cast<T>(std::abs(value));
+ return static_cast<T>(*validity == RANGE_VALID ? std::abs(value) : 0);
}
template <typename T>
« no previous file with comments | « no previous file | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698