summaryrefslogtreecommitdiff
path: root/chromium/base/numerics
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-12 15:59:20 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-25 06:57:22 +0000
commitf7eaed5286974984ba5f9e3189d8f49d03e99f81 (patch)
treecaed19b2af2024f35449fb0b781d0a25e09d4f8f /chromium/base/numerics
parent9729c4479fe23554eae6e6dd1f30ff488f470c84 (diff)
downloadqtwebengine-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.h4
-rw-r--r--chromium/base/numerics/checked_math_impl.h13
-rw-r--r--chromium/base/numerics/clamped_math.h6
-rw-r--r--chromium/base/numerics/clamped_math_impl.h10
-rw-r--r--chromium/base/numerics/ranges.h19
-rw-r--r--chromium/base/numerics/safe_conversions.h3
-rw-r--r--chromium/base/numerics/safe_conversions_arm_impl.h4
-rw-r--r--chromium/base/numerics/safe_conversions_impl.h34
-rw-r--r--chromium/base/numerics/safe_math_arm_impl.h14
-rw-r--r--chromium/base/numerics/safe_math_shared_impl.h2
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.