From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../chromium/base/numerics/safe_math_shared_impl.h | 240 +++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 security/sandbox/chromium/base/numerics/safe_math_shared_impl.h (limited to 'security/sandbox/chromium/base/numerics/safe_math_shared_impl.h') diff --git a/security/sandbox/chromium/base/numerics/safe_math_shared_impl.h b/security/sandbox/chromium/base/numerics/safe_math_shared_impl.h new file mode 100644 index 0000000000..3556b1ea81 --- /dev/null +++ b/security/sandbox/chromium/base/numerics/safe_math_shared_impl.h @@ -0,0 +1,240 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_ +#define BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "base/numerics/safe_conversions.h" + +#ifdef __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. +#elif !defined(__native_client__) && \ + ((defined(__clang__) && \ + ((__clang_major__ > 3) || \ + (__clang_major__ == 3 && __clang_minor__ >= 4))) || \ + (defined(__GNUC__) && __GNUC__ >= 5)) +#include "base/numerics/safe_math_clang_gcc_impl.h" +#define BASE_HAS_OPTIMIZED_SAFE_MATH (1) +#else +#define BASE_HAS_OPTIMIZED_SAFE_MATH (0) +#endif + +namespace base { +namespace internal { + +// These are the non-functioning boilerplate implementations of the optimized +// safe math routines. +#if !BASE_HAS_OPTIMIZED_SAFE_MATH +template +struct CheckedAddFastOp { + static const bool is_supported = false; + template + static constexpr bool Do(T, U, V*) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; + +template +struct CheckedSubFastOp { + static const bool is_supported = false; + template + static constexpr bool Do(T, U, V*) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; + +template +struct CheckedMulFastOp { + static const bool is_supported = false; + template + static constexpr bool Do(T, U, V*) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; + +template +struct ClampedAddFastOp { + static const bool is_supported = false; + template + static constexpr V Do(T, U) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; + +template +struct ClampedSubFastOp { + static const bool is_supported = false; + template + static constexpr V Do(T, U) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; + +template +struct ClampedMulFastOp { + static const bool is_supported = false; + template + static constexpr V Do(T, U) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; + +template +struct ClampedNegFastOp { + static const bool is_supported = false; + static constexpr T Do(T) { + // Force a compile failure if instantiated. + return CheckOnFailure::template HandleFailure(); + } +}; +#endif // BASE_HAS_OPTIMIZED_SAFE_MATH +#undef BASE_HAS_OPTIMIZED_SAFE_MATH + +// 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, +// so the float versions will not compile. +template ::value, + bool IsFloat = std::is_floating_point::value> +struct UnsignedOrFloatForSize; + +template +struct UnsignedOrFloatForSize { + using type = typename std::make_unsigned::type; +}; + +template +struct UnsignedOrFloatForSize { + using type = Numeric; +}; + +// Wrap the unary operations to allow SFINAE when instantiating integrals versus +// floating points. These don't perform any overflow checking. Rather, they +// exhibit well-defined overflow semantics and rely on the caller to detect +// if an overflow occured. + +template ::value>::type* = nullptr> +constexpr T NegateWrapper(T value) { + using UnsignedT = typename std::make_unsigned::type; + // This will compile to a NEG on Intel, and is normal negation on ARM. + return static_cast(UnsignedT(0) - static_cast(value)); +} + +template < + typename T, + typename std::enable_if::value>::type* = nullptr> +constexpr T NegateWrapper(T value) { + return -value; +} + +template ::value>::type* = nullptr> +constexpr typename std::make_unsigned::type InvertWrapper(T value) { + return ~value; +} + +template ::value>::type* = nullptr> +constexpr T AbsWrapper(T value) { + return static_cast(SafeUnsignedAbs(value)); +} + +template < + typename T, + typename std::enable_if::value>::type* = nullptr> +constexpr T AbsWrapper(T value) { + return value < 0 ? -value : value; +} + +template