tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

safe_math_clang_gcc_impl.h (4872B)


      1 // Copyright 2017 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
      6 #define BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
      7 
      8 #include <cassert>
      9 #include <limits>
     10 #include <type_traits>
     11 
     12 #include "base/numerics/safe_conversions.h"
     13 
     14 #if !defined(__native_client__) && (defined(__ARMEL__) || defined(__arch64__))
     15 #include "base/numerics/safe_math_arm_impl.h"
     16 #define BASE_HAS_ASSEMBLER_SAFE_MATH (1)
     17 #else
     18 #define BASE_HAS_ASSEMBLER_SAFE_MATH (0)
     19 #endif
     20 
     21 namespace base {
     22 namespace internal {
     23 
     24 // These are the non-functioning boilerplate implementations of the optimized
     25 // safe math routines.
     26 #if !BASE_HAS_ASSEMBLER_SAFE_MATH
     27 template <typename T, typename U>
     28 struct CheckedMulFastAsmOp {
     29  static const bool is_supported = false;
     30  template <typename V>
     31  static constexpr bool Do(T, U, V*) {
     32    // Force a compile failure if instantiated.
     33    return CheckOnFailure::template HandleFailure<bool>();
     34  }
     35 };
     36 
     37 template <typename T, typename U>
     38 struct ClampedAddFastAsmOp {
     39  static const bool is_supported = false;
     40  template <typename V>
     41  static constexpr V Do(T, U) {
     42    // Force a compile failure if instantiated.
     43    return CheckOnFailure::template HandleFailure<V>();
     44  }
     45 };
     46 
     47 template <typename T, typename U>
     48 struct ClampedSubFastAsmOp {
     49  static const bool is_supported = false;
     50  template <typename V>
     51  static constexpr V Do(T, U) {
     52    // Force a compile failure if instantiated.
     53    return CheckOnFailure::template HandleFailure<V>();
     54  }
     55 };
     56 
     57 template <typename T, typename U>
     58 struct ClampedMulFastAsmOp {
     59  static const bool is_supported = false;
     60  template <typename V>
     61  static constexpr V Do(T, U) {
     62    // Force a compile failure if instantiated.
     63    return CheckOnFailure::template HandleFailure<V>();
     64  }
     65 };
     66 #endif  // BASE_HAS_ASSEMBLER_SAFE_MATH
     67 #undef BASE_HAS_ASSEMBLER_SAFE_MATH
     68 
     69 template <typename T, typename U>
     70 struct CheckedAddFastOp {
     71  static const bool is_supported = true;
     72  template <typename V>
     73  __attribute__((always_inline)) static constexpr bool Do(T x, U y, V* result) {
     74    return !__builtin_add_overflow(x, y, result);
     75  }
     76 };
     77 
     78 template <typename T, typename U>
     79 struct CheckedSubFastOp {
     80  static const bool is_supported = true;
     81  template <typename V>
     82  __attribute__((always_inline)) static constexpr bool Do(T x, U y, V* result) {
     83    return !__builtin_sub_overflow(x, y, result);
     84  }
     85 };
     86 
     87 template <typename T, typename U>
     88 struct CheckedMulFastOp {
     89 #if defined(__clang__)
     90  // TODO(jschuh): Get the Clang runtime library issues sorted out so we can
     91  // support full-width, mixed-sign multiply builtins.
     92  // https://crbug.com/613003
     93  // We can support intptr_t, uintptr_t, or a smaller common type.
     94  static const bool is_supported =
     95      (IsTypeInRangeForNumericType<intptr_t, T>::value &&
     96       IsTypeInRangeForNumericType<intptr_t, U>::value) ||
     97      (IsTypeInRangeForNumericType<uintptr_t, T>::value &&
     98       IsTypeInRangeForNumericType<uintptr_t, U>::value);
     99 #else
    100  static const bool is_supported = true;
    101 #endif
    102  template <typename V>
    103  __attribute__((always_inline)) static constexpr bool Do(T x, U y, V* result) {
    104    return CheckedMulFastAsmOp<T, U>::is_supported
    105               ? CheckedMulFastAsmOp<T, U>::Do(x, y, result)
    106               : !__builtin_mul_overflow(x, y, result);
    107  }
    108 };
    109 
    110 template <typename T, typename U>
    111 struct ClampedAddFastOp {
    112  static const bool is_supported = ClampedAddFastAsmOp<T, U>::is_supported;
    113  template <typename V>
    114  __attribute__((always_inline)) static V Do(T x, U y) {
    115    return ClampedAddFastAsmOp<T, U>::template Do<V>(x, y);
    116  }
    117 };
    118 
    119 template <typename T, typename U>
    120 struct ClampedSubFastOp {
    121  static const bool is_supported = ClampedSubFastAsmOp<T, U>::is_supported;
    122  template <typename V>
    123  __attribute__((always_inline)) static V Do(T x, U y) {
    124    return ClampedSubFastAsmOp<T, U>::template Do<V>(x, y);
    125  }
    126 };
    127 
    128 template <typename T, typename U>
    129 struct ClampedMulFastOp {
    130  static const bool is_supported = ClampedMulFastAsmOp<T, U>::is_supported;
    131  template <typename V>
    132  __attribute__((always_inline)) static V Do(T x, U y) {
    133    return ClampedMulFastAsmOp<T, U>::template Do<V>(x, y);
    134  }
    135 };
    136 
    137 template <typename T>
    138 struct ClampedNegFastOp {
    139  static const bool is_supported = std::is_signed_v<T>;
    140  __attribute__((always_inline)) static T Do(T value) {
    141    // Use this when there is no assembler path available.
    142    if (!ClampedSubFastAsmOp<T, T>::is_supported) {
    143      T result;
    144      return !__builtin_sub_overflow(T(0), value, &result)
    145                 ? result
    146                 : std::numeric_limits<T>::max();
    147    }
    148 
    149    // Fallback to the normal subtraction path.
    150    return ClampedSubFastOp<T, T>::template Do<T>(T(0), value);
    151  }
    152 };
    153 
    154 }  // namespace internal
    155 }  // namespace base
    156 
    157 #endif  // BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_