diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-05-12 15:59:20 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-05-25 06:57:22 +0000 |
commit | f7eaed5286974984ba5f9e3189d8f49d03e99f81 (patch) | |
tree | caed19b2af2024f35449fb0b781d0a25e09d4f8f /chromium/base/numerics | |
parent | 9729c4479fe23554eae6e6dd1f30ff488f470c84 (diff) | |
download | qtwebengine-chromium-f7eaed5286974984ba5f9e3189d8f49d03e99f81.tar.gz |
BASELINE: Update Chromium to 100.0.4896.167
Change-Id: I98cbeb5d7543d966ffe04d8cefded0c493a11333
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/numerics')
-rw-r--r-- | chromium/base/numerics/checked_math.h | 4 | ||||
-rw-r--r-- | chromium/base/numerics/checked_math_impl.h | 13 | ||||
-rw-r--r-- | chromium/base/numerics/clamped_math.h | 6 | ||||
-rw-r--r-- | chromium/base/numerics/clamped_math_impl.h | 10 | ||||
-rw-r--r-- | chromium/base/numerics/ranges.h | 19 | ||||
-rw-r--r-- | chromium/base/numerics/safe_conversions.h | 3 | ||||
-rw-r--r-- | chromium/base/numerics/safe_conversions_arm_impl.h | 4 | ||||
-rw-r--r-- | chromium/base/numerics/safe_conversions_impl.h | 34 | ||||
-rw-r--r-- | chromium/base/numerics/safe_math_arm_impl.h | 14 | ||||
-rw-r--r-- | chromium/base/numerics/safe_math_shared_impl.h | 2 |
10 files changed, 38 insertions, 71 deletions
diff --git a/chromium/base/numerics/checked_math.h b/chromium/base/numerics/checked_math.h index a2268c0d3b9..bbc575c457b 100644 --- a/chromium/base/numerics/checked_math.h +++ b/chromium/base/numerics/checked_math.h @@ -38,7 +38,7 @@ class CheckedNumeric { template <typename Src> constexpr CheckedNumeric(Src value) // NOLINT(runtime/explicit) : state_(value) { - static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric."); + static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric."); } // This is not an explicit constructor because we want a seamless conversion @@ -139,7 +139,7 @@ class CheckedNumeric { constexpr CheckedNumeric operator-() const { // Use an optimized code path for a known run-time variable. - if (!MustTreatAsConstexpr(state_.value()) && std::is_signed<T>::value && + if (!IsConstantEvaluated() && std::is_signed<T>::value && std::is_floating_point<T>::value) { return FastRuntimeNegate(); } diff --git a/chromium/base/numerics/checked_math_impl.h b/chromium/base/numerics/checked_math_impl.h index 82495400554..1b83a0d059c 100644 --- a/chromium/base/numerics/checked_math_impl.h +++ b/chromium/base/numerics/checked_math_impl.h @@ -51,8 +51,7 @@ struct CheckedAddOp<T, using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { - // TODO(jschuh) Make this "constexpr if" once we're C++17. - if (CheckedAddFastOp<T, U>::is_supported) + if constexpr (CheckedAddFastOp<T, U>::is_supported) return CheckedAddFastOp<T, U>::Do(x, y, result); // Double the underlying type up to a full machine word. @@ -115,8 +114,7 @@ struct CheckedSubOp<T, using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { - // TODO(jschuh) Make this "constexpr if" once we're C++17. - if (CheckedSubFastOp<T, U>::is_supported) + if constexpr (CheckedSubFastOp<T, U>::is_supported) return CheckedSubFastOp<T, U>::Do(x, y, result); // Double the underlying type up to a full machine word. @@ -181,8 +179,7 @@ struct CheckedMulOp<T, using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { - // TODO(jschuh) Make this "constexpr if" once we're C++17. - if (CheckedMulFastOp<T, U>::is_supported) + if constexpr (CheckedMulFastOp<T, U>::is_supported) return CheckedMulFastOp<T, U>::Do(x, y, result); using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type; @@ -334,7 +331,7 @@ struct CheckedRshOp<T, std::is_integral<U>::value>::type> { using result_type = T; template <typename V> - static bool Do(T x, U shift, V* result) { + static constexpr bool Do(T x, U shift, V* result) { // Use sign conversion to push negative values out of range. if (BASE_NUMERICS_UNLIKELY(as_unsigned(shift) >= IntegerBitsPlusSign<T>::value)) { @@ -564,7 +561,7 @@ class CheckedNumericState<T, NUMERIC_FLOATING> { constexpr bool is_valid() const { // Written this way because std::isfinite is not reliably constexpr. - return MustTreatAsConstexpr(value_) + return IsConstantEvaluated() ? value_ <= std::numeric_limits<T>::max() && value_ >= std::numeric_limits<T>::lowest() : std::isfinite(value_); diff --git a/chromium/base/numerics/clamped_math.h b/chromium/base/numerics/clamped_math.h index e84d149d99d..20e2eb47150 100644 --- a/chromium/base/numerics/clamped_math.h +++ b/chromium/base/numerics/clamped_math.h @@ -38,7 +38,7 @@ class ClampedNumeric { template <typename Src> constexpr ClampedNumeric(Src value) // NOLINT(runtime/explicit) : value_(saturated_cast<T>(value)) { - static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric."); + static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric."); } // This is not an explicit constructor because we want a seamless conversion @@ -178,8 +178,8 @@ class ClampedNumeric { // ClampedNumeric and POD arithmetic types. template <typename Src> struct Wrapper { - static constexpr Src value(Src value) { - return static_cast<typename UnderlyingType<Src>::type>(value); + static constexpr typename UnderlyingType<Src>::type value(Src value) { + return value; } }; }; diff --git a/chromium/base/numerics/clamped_math_impl.h b/chromium/base/numerics/clamped_math_impl.h index 303a7e945a1..061f8c42120 100644 --- a/chromium/base/numerics/clamped_math_impl.h +++ b/chromium/base/numerics/clamped_math_impl.h @@ -25,7 +25,7 @@ template <typename T, typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value>::type* = nullptr> constexpr T SaturatedNegWrapper(T value) { - return MustTreatAsConstexpr(value) || !ClampedNegFastOp<T>::is_supported + return IsConstantEvaluated() || !ClampedNegFastOp<T>::is_supported ? (NegateWrapper(value) != std::numeric_limits<T>::lowest() ? NegateWrapper(value) : std::numeric_limits<T>::max()) @@ -79,7 +79,7 @@ struct ClampedAddOp<T, using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { - if (ClampedAddFastOp<T, U>::is_supported) + if (!IsConstantEvaluated() && ClampedAddFastOp<T, U>::is_supported) return ClampedAddFastOp<T, U>::template Do<V>(x, y); static_assert(std::is_same<V, result_type>::value || @@ -105,8 +105,7 @@ struct ClampedSubOp<T, using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { - // TODO(jschuh) Make this "constexpr if" once we're C++17. - if (ClampedSubFastOp<T, U>::is_supported) + if (!IsConstantEvaluated() && ClampedSubFastOp<T, U>::is_supported) return ClampedSubFastOp<T, U>::template Do<V>(x, y); static_assert(std::is_same<V, result_type>::value || @@ -132,8 +131,7 @@ struct ClampedMulOp<T, using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { - // TODO(jschuh) Make this "constexpr if" once we're C++17. - if (ClampedMulFastOp<T, U>::is_supported) + if (!IsConstantEvaluated() && ClampedMulFastOp<T, U>::is_supported) return ClampedMulFastOp<T, U>::template Do<V>(x, y); V result = {}; diff --git a/chromium/base/numerics/ranges.h b/chromium/base/numerics/ranges.h index 58deb6feecb..ebe1302b3d5 100644 --- a/chromium/base/numerics/ranges.h +++ b/chromium/base/numerics/ranges.h @@ -5,28 +5,11 @@ #ifndef BASE_NUMERICS_RANGES_H_ #define BASE_NUMERICS_RANGES_H_ -#include <algorithm> #include <cmath> +#include <type_traits> namespace base { -// DO NOT USE THIS FUNCTION. IT IS DUE TO BE REMOVED. https://crbug.com/1231569 -// Please use base::clamp() from base/cxx17_backports.h instead. -// -// This function, unlike base::clamp(), does not check if `min` is greater than -// `max`, and returns a bogus answer if it is. Please migrate all code that -// calls this function to use base::clamp() instead. -// -// If, for some reason the broken behavior is required, please re-create this -// min/max nesting inline in the host code and explain with a comment why it -// is needed. -template <class T> -constexpr const T& BrokenClampThatShouldNotBeUsed(const T& value, - const T& min, - const T& max) { - return std::min(std::max(value, min), max); -} - template <typename T> constexpr bool IsApproximatelyEqual(T lhs, T rhs, T tolerance) { static_assert(std::is_arithmetic<T>::value, "Argument must be arithmetic"); diff --git a/chromium/base/numerics/safe_conversions.h b/chromium/base/numerics/safe_conversions.h index 2bc8dd7c1bc..f41742c5f6e 100644 --- a/chromium/base/numerics/safe_conversions.h +++ b/chromium/base/numerics/safe_conversions.h @@ -204,8 +204,7 @@ template <typename Dst, typename Src> constexpr Dst saturated_cast(Src value) { using SrcType = typename UnderlyingType<Src>::type; - return !IsCompileTimeConstant(value) && - SaturateFastOp<Dst, SrcType>::is_supported && + return !IsConstantEvaluated() && SaturateFastOp<Dst, SrcType>::is_supported && std::is_same<SaturationHandler<Dst>, SaturationDefaultLimits<Dst>>::value ? SaturateFastOp<Dst, SrcType>::Do(static_cast<SrcType>(value)) diff --git a/chromium/base/numerics/safe_conversions_arm_impl.h b/chromium/base/numerics/safe_conversions_arm_impl.h index cf31072b9b8..afc84df2dfd 100644 --- a/chromium/base/numerics/safe_conversions_arm_impl.h +++ b/chromium/base/numerics/safe_conversions_arm_impl.h @@ -18,8 +18,8 @@ namespace internal { template <typename Dst, typename Src> struct SaturateFastAsmOp { static constexpr bool is_supported = - std::is_signed<Src>::value && std::is_integral<Dst>::value && - std::is_integral<Src>::value && + kEnableAsmCode && std::is_signed<Src>::value && + std::is_integral<Dst>::value && std::is_integral<Src>::value && IntegerBitsPlusSign<Src>::value <= IntegerBitsPlusSign<int32_t>::value && IntegerBitsPlusSign<Dst>::value <= IntegerBitsPlusSign<int32_t>::value && !IsTypeInRangeForNumericType<Dst, Src>::value; diff --git a/chromium/base/numerics/safe_conversions_impl.h b/chromium/base/numerics/safe_conversions_impl.h index c1f8f7c13d0..d45f14f1f33 100644 --- a/chromium/base/numerics/safe_conversions_impl.h +++ b/chromium/base/numerics/safe_conversions_impl.h @@ -85,30 +85,18 @@ constexpr typename std::make_unsigned<T>::type SafeUnsignedAbs(T value) { : static_cast<UnsignedT>(value); } -// This allows us to switch paths on known compile-time constants. -#if defined(__clang__) || defined(__GNUC__) -constexpr bool CanDetectCompileTimeConstant() { - return true; -} -template <typename T> -constexpr bool IsCompileTimeConstant(const T v) { - return __builtin_constant_p(v); -} +// TODO(jschuh): Switch to std::is_constant_evaluated() once C++20 is supported. +// Alternately, the usage could be restructured for "consteval if" in C++23. +#define IsConstantEvaluated() (__builtin_is_constant_evaluated()) + +// TODO(jschuh): Debug builds don't reliably propagate constants, so we restrict +// some accelerated runtime paths to release builds until this can be forced +// with consteval support in C++20 or C++23. +#if defined(NDEBUG) +constexpr bool kEnableAsmCode = true; #else -constexpr bool CanDetectCompileTimeConstant() { - return false; -} -template <typename T> -constexpr bool IsCompileTimeConstant(const T) { - return false; -} +constexpr bool kEnableAsmCode = false; #endif -template <typename T> -constexpr bool MustTreatAsConstexpr(const T v) { - // Either we can't detect a compile-time constant, and must always use the - // constexpr path, or we know we have a compile-time constant. - return !CanDetectCompileTimeConstant() || IsCompileTimeConstant(v); -} // Forces a crash, like a CHECK(false). Used for numeric boundary errors. // Also used in a constexpr template to trigger a compilation failure on @@ -193,7 +181,7 @@ class RangeCheck { public: constexpr RangeCheck(bool is_in_lower_bound, bool is_in_upper_bound) : is_underflow_(!is_in_lower_bound), is_overflow_(!is_in_upper_bound) {} - constexpr RangeCheck() : is_underflow_(0), is_overflow_(0) {} + constexpr RangeCheck() : is_underflow_(false), is_overflow_(false) {} constexpr bool IsValid() const { return !is_overflow_ && !is_underflow_; } constexpr bool IsInvalid() const { return is_overflow_ && is_underflow_; } constexpr bool IsOverflow() const { return is_overflow_ && !is_underflow_; } diff --git a/chromium/base/numerics/safe_math_arm_impl.h b/chromium/base/numerics/safe_math_arm_impl.h index dcf33a3d199..67a84cf9428 100644 --- a/chromium/base/numerics/safe_math_arm_impl.h +++ b/chromium/base/numerics/safe_math_arm_impl.h @@ -16,9 +16,10 @@ namespace internal { template <typename T, typename U> struct CheckedMulFastAsmOp { static const bool is_supported = - FastIntegerArithmeticPromotion<T, U>::is_contained; + kEnableAsmCode && FastIntegerArithmeticPromotion<T, U>::is_contained; - // The following is much more efficient than the Clang and GCC builtins for + // The following is not an assembler routine and is thus constexpr safe, it + // just emits much more efficient code than the Clang and GCC builtins for // performing overflow-checked multiplication when a twice wider type is // available. The below compiles down to 2-3 instructions, depending on the // width of the types in use. @@ -30,7 +31,7 @@ struct CheckedMulFastAsmOp { // asr r2, r1, #16 // cmp r2, r1, asr #15 template <typename V> - __attribute__((always_inline)) static bool Do(T x, U y, V* result) { + static constexpr bool Do(T x, U y, V* result) { using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type; Promotion presult; @@ -45,7 +46,7 @@ struct CheckedMulFastAsmOp { template <typename T, typename U> struct ClampedAddFastAsmOp { static const bool is_supported = - BigEnoughPromotion<T, U>::is_contained && + kEnableAsmCode && BigEnoughPromotion<T, U>::is_contained && IsTypeInRangeForNumericType< int32_t, typename BigEnoughPromotion<T, U>::type>::value; @@ -71,7 +72,7 @@ struct ClampedAddFastAsmOp { template <typename T, typename U> struct ClampedSubFastAsmOp { static const bool is_supported = - BigEnoughPromotion<T, U>::is_contained && + kEnableAsmCode && BigEnoughPromotion<T, U>::is_contained && IsTypeInRangeForNumericType< int32_t, typename BigEnoughPromotion<T, U>::type>::value; @@ -96,7 +97,8 @@ struct ClampedSubFastAsmOp { template <typename T, typename U> struct ClampedMulFastAsmOp { - static const bool is_supported = CheckedMulFastAsmOp<T, U>::is_supported; + static const bool is_supported = + kEnableAsmCode && CheckedMulFastAsmOp<T, U>::is_supported; template <typename V> __attribute__((always_inline)) static V Do(T x, U y) { diff --git a/chromium/base/numerics/safe_math_shared_impl.h b/chromium/base/numerics/safe_math_shared_impl.h index f2e5e7ef470..ba91016758e 100644 --- a/chromium/base/numerics/safe_math_shared_impl.h +++ b/chromium/base/numerics/safe_math_shared_impl.h @@ -18,7 +18,7 @@ #include "base/numerics/safe_conversions.h" #include "build/build_config.h" -#if defined(OS_ASMJS) +#if BUILDFLAG(IS_ASMJS) // Optimized safe math instructions are incompatible with asmjs. #define BASE_HAS_OPTIMIZED_SAFE_MATH (0) // Where available use builtin math overflow support on Clang and GCC. |