chromium/base/safe_numerics_unittest.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include <stddef.h>
#include <stdint.h>

#include <limits>
#include <type_traits>

#include "base/compiler_specific.h"
#include "build/build_config.h"

// WARNING: This block must come before the base/numerics headers are included.
// These tests deliberately cause arithmetic boundary errors. If the compiler is
// aggressive enough, it can const detect these errors, so we disable warnings.
#if BUILDFLAG(IS_WIN)
#pragma warning(disable : 4756)  // Arithmetic overflow.
#pragma warning(disable : 4293)  // Invalid shift.
#endif

// This may not need to come before the base/numerics headers, but let's keep
// it close to the MSVC equivalent.
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winteger-overflow"
#endif

#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "base/numerics/wrapping_math.h"
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
#include <mmintrin.h>
#endif

namespace base {
namespace internal {

numeric_limits;

// This is a helper function for finding the maximum value in Src that can be
// wholy represented as the destination floating-point type.
template <typename Dst, typename Src>
Dst GetMaxConvertibleToFloat() {}

// Test corner case promotions used
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;

// Test compile-time (constexpr) evaluation of checking and saturation.
constexpr int32_t kIntOne =;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
constexpr float kFloatOne =;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;
static_assert;

template <typename U>
U GetNumericValueForTest(const CheckedNumeric<U>& src) {}

template <typename U>
U GetNumericValueForTest(const ClampedNumeric<U>& src) {}

template <typename U>
U GetNumericValueForTest(const U& src) {}

// Logs the ValueOrDie() failure instead of crashing.
struct LogOnFailure {};

template <typename T>
constexpr T GetValue(const T& src) {}

template <typename T, typename U>
constexpr T GetValueAsDest(const U& src) {}

template <typename T>
constexpr T GetValue(const CheckedNumeric<T>& src) {}

template <typename T, typename U>
constexpr T GetValueAsDest(const CheckedNumeric<U>& src) {}

template <typename T>
constexpr T GetValue(const ClampedNumeric<T>& src) {}

template <typename T, typename U>
constexpr T GetValueAsDest(const ClampedNumeric<U>& src) {}

// Helper macros to wrap displaying the conversion types and line numbers.
#define TEST_EXPECTED_VALIDITY(expected, actual)

#define TEST_EXPECTED_SUCCESS(actual)
#define TEST_EXPECTED_FAILURE(actual)

// We have to handle promotions, so infer the underlying type below from actual.
#define TEST_EXPECTED_VALUE(expected, actual)

// Test the simple pointer arithmetic overrides.
template <typename Dst>
void TestStrictPointerMath() {}

// Signed integer arithmetic.
template <typename Dst>
static void TestSpecializedArithmetic(
    const char* dst,
    int line,
    std::enable_if_t<numeric_limits<Dst>::is_integer &&
                         numeric_limits<Dst>::is_signed,
                     int> = 0) {}

// Unsigned integer arithmetic.
template <typename Dst>
static void TestSpecializedArithmetic(
    const char* dst,
    int line,
    std::enable_if_t<numeric_limits<Dst>::is_integer &&
                         !numeric_limits<Dst>::is_signed,
                     int> = 0) {}

// Floating point arithmetic.
template <typename Dst>
void TestSpecializedArithmetic(
    const char* dst,
    int line,
    std::enable_if_t<numeric_limits<Dst>::is_iec559, int> = 0) {}

// Generic arithmetic tests.
template <typename Dst>
static void TestArithmetic(const char* dst, int line) {}

// Helper macro to wrap displaying the conversion types and line numbers.
#define TEST_ARITHMETIC(Dst)

TEST(SafeNumerics, SignedIntegerMath) {}

TEST(SafeNumerics, UnsignedIntegerMath) {}

TEST(SafeNumerics, FloatingPointMath) {}

// Enumerates the five different conversions types we need to test.
enum NumericConversionType {};

// Template covering the different conversion tests.
template <typename Dst, typename Src, NumericConversionType conversion>
struct TestNumericConversion {};

enum RangeConstraint {};

// These are some wrappers to make the tests a bit cleaner.
constexpr RangeConstraint RangeCheckToEnum(const RangeCheck constraint) {}

// EXPECT_EQ wrappers providing specific detail on test failures.
#define TEST_EXPECTED_RANGE(expected, actual)

template <typename Dst, typename Src>
void TestStrictComparison(const char* dst, const char* src, int line) {}

TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING>;

TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW>;

TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL>;

TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW>;

TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL>;

// Helper macro to wrap displaying the conversion types and line numbers
#define TEST_NUMERIC_CONVERSION(d, s, t)

TEST(SafeNumerics, IntMinOperations) {}

TEST(SafeNumerics, Int16Operations) {}

TEST(SafeNumerics, IntOperations) {}

TEST(SafeNumerics, IntMaxOperations) {}

TEST(SafeNumerics, FloatOperations) {}

TEST(SafeNumerics, DoubleOperations) {}

TEST(SafeNumerics, SizeTOperations) {}

// A one-off test to ensure StrictNumeric won't resolve to an incorrect type.
// If this fails we'll just get a compiler error on an ambiguous overload.
int TestOverload(int) {}
uint8_t TestOverload(uint8_t) {}
size_t TestOverload(size_t) {}

static_assert;
static_assert;

template <typename T>
struct CastTest1 {};

template <typename T>
struct CastTest2 {};

TEST(SafeNumerics, CastTests) {}

TEST(SafeNumerics, IsValueInRangeForNumericType) {}

TEST(SafeNumerics, CompoundNumericOperations) {}

TEST(SafeNumerics, TemplatedSafeMath) {}

TEST(SafeNumerics, VariadicNumericOperations) {}

TEST(SafeNumerics, CeilInt) {}

TEST(SafeNumerics, FloorInt) {}

TEST(SafeNumerics, RoundInt) {}

TEST(SafeNumerics, Int64) {}

template <typename T>
void TestWrappingMathSigned() {}

template <typename T>
void TestWrappingMathUnsigned() {}

TEST(SafeNumerics, WrappingMath) {}

#if defined(__clang__)
#pragma clang diagnostic pop  // -Winteger-overflow
#endif

}  // namespace internal
}  // namespace base