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

Unified Diff: base/numerics/safe_math_impl.h

Issue 2528243002: Fix silent truncations when extracting values from CheckedNumeric (Closed)
Patch Set: compile fix Created 4 years 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 | « base/numerics/safe_math.h ('k') | 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 15de619e76fae11ce35d8ecac5b950c4e7ba432b..c6fbf704cc6a75db199db406f6a16a598885ae36 100644
--- a/base/numerics/safe_math_impl.h
+++ b/base/numerics/safe_math_impl.h
@@ -23,78 +23,6 @@ namespace internal {
// but it may not be fast. This code could be split based on
// platform/architecture and replaced with potentially faster implementations.
-// Integer promotion templates used by the portable checked integer arithmetic.
-template <size_t Size, bool IsSigned>
-struct IntegerForSizeAndSign;
-template <>
-struct IntegerForSizeAndSign<1, true> {
- typedef int8_t type;
-};
-template <>
-struct IntegerForSizeAndSign<1, false> {
- typedef uint8_t type;
-};
-template <>
-struct IntegerForSizeAndSign<2, true> {
- typedef int16_t type;
-};
-template <>
-struct IntegerForSizeAndSign<2, false> {
- typedef uint16_t type;
-};
-template <>
-struct IntegerForSizeAndSign<4, true> {
- typedef int32_t type;
-};
-template <>
-struct IntegerForSizeAndSign<4, false> {
- typedef uint32_t type;
-};
-template <>
-struct IntegerForSizeAndSign<8, true> {
- typedef int64_t type;
-};
-template <>
-struct IntegerForSizeAndSign<8, false> {
- typedef uint64_t type;
- static_assert(sizeof(uintmax_t) == 8,
- "Max integer size not supported for this toolchain.");
-};
-
-// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to
-// support 128-bit math, then the ArithmeticPromotion template below will need
-// to be updated (or more likely replaced with a decltype expression).
-
-template <typename Integer>
-struct UnsignedIntegerForSize {
- typedef typename std::enable_if<
- std::numeric_limits<Integer>::is_integer,
- typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type type;
-};
-
-template <typename Integer>
-struct SignedIntegerForSize {
- typedef typename std::enable_if<
- std::numeric_limits<Integer>::is_integer,
- typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type type;
-};
-
-template <typename Integer>
-struct TwiceWiderInteger {
- typedef typename std::enable_if<
- std::numeric_limits<Integer>::is_integer,
- typename IntegerForSizeAndSign<
- sizeof(Integer) * 2,
- std::numeric_limits<Integer>::is_signed>::type>::type type;
-};
-
-template <typename Integer>
-struct PositionOfSignBit {
- static const typename std::enable_if<std::numeric_limits<Integer>::is_integer,
- size_t>::type value =
- CHAR_BIT * sizeof(Integer) - 1;
-};
-
// This is used for UnsignedAbs, where we need to support floating-point
// template instantiations even though we don't actually support the operations.
// However, there is no corresponding implementation of e.g. SafeUnsignedAbs,
@@ -129,106 +57,6 @@ constexpr T BinaryComplement(T x) {
return static_cast<T>(~x);
}
-enum ArithmeticPromotionCategory {
- LEFT_PROMOTION, // Use the type of the left-hand argument.
- RIGHT_PROMOTION, // Use the type of the right-hand argument.
- MAX_EXPONENT_PROMOTION, // Use the type supporting the largest exponent.
- BIG_ENOUGH_PROMOTION // Attempt to find a big enough type.
-};
-
-template <ArithmeticPromotionCategory Promotion,
- typename Lhs,
- typename Rhs = Lhs>
-struct ArithmeticPromotion;
-
-template <typename Lhs,
- typename Rhs,
- ArithmeticPromotionCategory Promotion =
- (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value)
- ? LEFT_PROMOTION
- : RIGHT_PROMOTION>
-struct MaxExponentPromotion;
-
-template <typename Lhs, typename Rhs>
-struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION> {
- using type = Lhs;
-};
-
-template <typename Lhs, typename Rhs>
-struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION> {
- using type = Rhs;
-};
-
-template <typename Lhs,
- typename Rhs = Lhs,
- bool is_intmax_type =
- std::is_integral<
- typename MaxExponentPromotion<Lhs, Rhs>::type>::value &&
- sizeof(typename MaxExponentPromotion<Lhs, Rhs>::type) ==
- sizeof(intmax_t),
- bool is_max_exponent =
- StaticDstRangeRelationToSrcRange<
- typename MaxExponentPromotion<Lhs, Rhs>::type,
- Lhs>::value ==
- NUMERIC_RANGE_CONTAINED&& StaticDstRangeRelationToSrcRange<
- typename MaxExponentPromotion<Lhs, Rhs>::type,
- Rhs>::value == NUMERIC_RANGE_CONTAINED>
-struct BigEnoughPromotion;
-
-// The side with the max exponent is big enough.
-template <typename Lhs, typename Rhs, bool is_intmax_type>
-struct BigEnoughPromotion<Lhs, Rhs, is_intmax_type, true> {
- using type = typename MaxExponentPromotion<Lhs, Rhs>::type;
- static const bool is_contained = true;
-};
-
-// We can use a twice wider type to fit.
-template <typename Lhs, typename Rhs>
-struct BigEnoughPromotion<Lhs, Rhs, false, false> {
- using type = typename IntegerForSizeAndSign<
- sizeof(typename MaxExponentPromotion<Lhs, Rhs>::type) * 2,
- std::is_signed<Lhs>::value || std::is_signed<Rhs>::value>::type;
- static const bool is_contained = true;
-};
-
-// No type is large enough.
-template <typename Lhs, typename Rhs>
-struct BigEnoughPromotion<Lhs, Rhs, true, false> {
- using type = typename MaxExponentPromotion<Lhs, Rhs>::type;
- static const bool is_contained = false;
-};
-
-// These are the supported promotion types.
-
-// Use the type supporting the largest exponent.
-template <typename Lhs, typename Rhs>
-struct ArithmeticPromotion<MAX_EXPONENT_PROMOTION, Lhs, Rhs> {
- using type = typename MaxExponentPromotion<Lhs, Rhs>::type;
- static const bool is_contained = true;
-};
-
-// Attempt to find a big enough type.
-template <typename Lhs, typename Rhs>
-struct ArithmeticPromotion<BIG_ENOUGH_PROMOTION, Lhs, Rhs> {
- using type = typename BigEnoughPromotion<Lhs, Rhs>::type;
- static const bool is_contained = BigEnoughPromotion<Lhs, Rhs>::is_contained;
-};
-
-// We can statically check if operations on the provided types can wrap, so we
-// can skip the checked operations if they're not needed. So, for an integer we
-// care if the destination type preserves the sign and is twice the width of
-// the source.
-template <typename T, typename Lhs, typename Rhs>
-struct IsIntegerArithmeticSafe {
- static const bool value = !std::numeric_limits<T>::is_iec559 &&
- StaticDstRangeRelationToSrcRange<T, Lhs>::value ==
- NUMERIC_RANGE_CONTAINED &&
- sizeof(T) >= (2 * sizeof(Lhs)) &&
- StaticDstRangeRelationToSrcRange<T, Rhs>::value !=
- NUMERIC_RANGE_CONTAINED &&
- sizeof(T) >= (2 * sizeof(Rhs));
-};
-
// Probe for builtin math overflow support on Clang and version check on GCC.
#if defined(__has_builtin)
#define USE_OVERFLOW_BUILTINS (__has_builtin(__builtin_add_overflow))
@@ -872,32 +700,6 @@ class CheckedNumericState<T, NUMERIC_FLOATING> {
constexpr T value() const { return value_; }
};
-// The following are helper templates used in the CheckedNumeric class.
-template <typename T>
-class CheckedNumeric;
-
-// Used to treat CheckedNumeric and arithmetic underlying types the same.
-template <typename T>
-struct UnderlyingType {
- using type = T;
- static const bool is_numeric = std::is_arithmetic<T>::value;
- static const bool is_checked = false;
-};
-
-template <typename T>
-struct UnderlyingType<CheckedNumeric<T>> {
- using type = T;
- static const bool is_numeric = true;
- static const bool is_checked = true;
-};
-
-template <typename L, typename R>
-struct IsCheckedOp {
- static const bool value =
- UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric &&
- (UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked);
-};
-
template <template <typename, typename, typename> class M,
typename L,
typename R>
« no previous file with comments | « base/numerics/safe_math.h ('k') | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698