Home | History | Annotate | Download | only in numerics
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stddef.h>
      6 #include <stdint.h>
      7 
      8 #include <limits>
      9 #include <type_traits>
     10 
     11 #include "base/compiler_specific.h"
     12 #include "base/numerics/safe_conversions.h"
     13 #include "base/numerics/safe_math.h"
     14 #include "base/template_util.h"
     15 #include "build/build_config.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
     19 #include <mmintrin.h>
     20 #endif
     21 
     22 using std::numeric_limits;
     23 using base::CheckedNumeric;
     24 using base::checked_cast;
     25 using base::IsValueInRangeForNumericType;
     26 using base::IsValueNegative;
     27 using base::SizeT;
     28 using base::StrictNumeric;
     29 using base::saturated_cast;
     30 using base::strict_cast;
     31 using base::internal::MaxExponent;
     32 using base::internal::RANGE_VALID;
     33 using base::internal::RANGE_INVALID;
     34 using base::internal::RANGE_OVERFLOW;
     35 using base::internal::RANGE_UNDERFLOW;
     36 using base::internal::SignedIntegerForSize;
     37 
     38 // These tests deliberately cause arithmetic overflows. If the compiler is
     39 // aggressive enough, it can const fold these overflows. Disable warnings about
     40 // overflows for const expressions.
     41 #if defined(OS_WIN)
     42 #pragma warning(disable:4756)
     43 #endif
     44 
     45 // This is a helper function for finding the maximum value in Src that can be
     46 // wholy represented as the destination floating-point type.
     47 template <typename Dst, typename Src>
     48 Dst GetMaxConvertibleToFloat() {
     49   typedef numeric_limits<Dst> DstLimits;
     50   typedef numeric_limits<Src> SrcLimits;
     51   static_assert(SrcLimits::is_specialized, "Source must be numeric.");
     52   static_assert(DstLimits::is_specialized, "Destination must be numeric.");
     53   CHECK(DstLimits::is_iec559);
     54 
     55   if (SrcLimits::digits <= DstLimits::digits &&
     56       MaxExponent<Src>::value <= MaxExponent<Dst>::value)
     57     return SrcLimits::max();
     58   Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
     59   while (max != static_cast<Src>(static_cast<Dst>(max))) {
     60     max /= 2;
     61   }
     62   return static_cast<Dst>(max);
     63 }
     64 
     65 // Helper macros to wrap displaying the conversion types and line numbers.
     66 #define TEST_EXPECTED_VALIDITY(expected, actual)                           \
     67   EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity())              \
     68       << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \
     69       << " on line " << line;
     70 
     71 #define TEST_EXPECTED_VALUE(expected, actual)                                \
     72   EXPECT_EQ(static_cast<Dst>(expected),                                      \
     73             CheckedNumeric<Dst>(actual).ValueUnsafe())                       \
     74       << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \
     75       << " on line " << line;
     76 
     77 // Signed integer arithmetic.
     78 template <typename Dst>
     79 static void TestSpecializedArithmetic(
     80     const char* dst,
     81     int line,
     82     typename std::enable_if<numeric_limits<Dst>::is_integer &&
     83                                 numeric_limits<Dst>::is_signed,
     84                             int>::type = 0) {
     85   typedef numeric_limits<Dst> DstLimits;
     86   TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW,
     87                          -CheckedNumeric<Dst>(DstLimits::min()));
     88   TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW,
     89                          CheckedNumeric<Dst>(DstLimits::min()).Abs());
     90   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
     91 
     92   TEST_EXPECTED_VALIDITY(RANGE_VALID,
     93                          CheckedNumeric<Dst>(DstLimits::max()) + -1);
     94   TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW,
     95                          CheckedNumeric<Dst>(DstLimits::min()) + -1);
     96   TEST_EXPECTED_VALIDITY(
     97       RANGE_UNDERFLOW,
     98       CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max());
     99 
    100   TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW,
    101                          CheckedNumeric<Dst>(DstLimits::min()) - 1);
    102   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    103                          CheckedNumeric<Dst>(DstLimits::min()) - -1);
    104   TEST_EXPECTED_VALIDITY(
    105       RANGE_OVERFLOW,
    106       CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max());
    107   TEST_EXPECTED_VALIDITY(
    108       RANGE_UNDERFLOW,
    109       CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max());
    110 
    111   TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW,
    112                          CheckedNumeric<Dst>(DstLimits::min()) * 2);
    113 
    114   TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW,
    115                          CheckedNumeric<Dst>(DstLimits::min()) / -1);
    116   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
    117 
    118   // Modulus is legal only for integers.
    119   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
    120   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
    121   TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
    122   TEST_EXPECTED_VALIDITY(RANGE_INVALID, CheckedNumeric<Dst>(-1) % -2);
    123   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
    124   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
    125   // Test all the different modulus combinations.
    126   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
    127   TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
    128   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
    129   CheckedNumeric<Dst> checked_dst = 1;
    130   TEST_EXPECTED_VALUE(0, checked_dst %= 1);
    131 }
    132 
    133 // Unsigned integer arithmetic.
    134 template <typename Dst>
    135 static void TestSpecializedArithmetic(
    136     const char* dst,
    137     int line,
    138     typename std::enable_if<numeric_limits<Dst>::is_integer &&
    139                                 !numeric_limits<Dst>::is_signed,
    140                             int>::type = 0) {
    141   typedef numeric_limits<Dst> DstLimits;
    142   TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min()));
    143   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    144                          CheckedNumeric<Dst>(DstLimits::min()).Abs());
    145   TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW,
    146                          CheckedNumeric<Dst>(DstLimits::min()) + -1);
    147   TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW,
    148                          CheckedNumeric<Dst>(DstLimits::min()) - 1);
    149   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2);
    150   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
    151   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    152                          CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs());
    153   TEST_EXPECTED_VALIDITY(
    154       RANGE_VALID,
    155       CheckedNumeric<typename SignedIntegerForSize<Dst>::type>(
    156           std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min())
    157           .UnsignedAbs());
    158 
    159   // Modulus is legal only for integers.
    160   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
    161   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
    162   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
    163   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
    164   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
    165   // Test all the different modulus combinations.
    166   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
    167   TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
    168   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
    169   CheckedNumeric<Dst> checked_dst = 1;
    170   TEST_EXPECTED_VALUE(0, checked_dst %= 1);
    171 }
    172 
    173 // Floating point arithmetic.
    174 template <typename Dst>
    175 void TestSpecializedArithmetic(
    176     const char* dst,
    177     int line,
    178     typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
    179   typedef numeric_limits<Dst> DstLimits;
    180   TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min()));
    181 
    182   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    183                          CheckedNumeric<Dst>(DstLimits::min()).Abs());
    184   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
    185 
    186   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    187                          CheckedNumeric<Dst>(DstLimits::min()) + -1);
    188   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    189                          CheckedNumeric<Dst>(DstLimits::max()) + 1);
    190   TEST_EXPECTED_VALIDITY(
    191       RANGE_UNDERFLOW,
    192       CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max());
    193 
    194   TEST_EXPECTED_VALIDITY(
    195       RANGE_OVERFLOW,
    196       CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max());
    197   TEST_EXPECTED_VALIDITY(
    198       RANGE_UNDERFLOW,
    199       CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max());
    200 
    201   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    202                          CheckedNumeric<Dst>(DstLimits::min()) * 2);
    203 
    204   TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
    205   EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating());
    206 }
    207 
    208 // Generic arithmetic tests.
    209 template <typename Dst>
    210 static void TestArithmetic(const char* dst, int line) {
    211   typedef numeric_limits<Dst> DstLimits;
    212 
    213   EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
    214   EXPECT_EQ(false,
    215             CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
    216                                 DstLimits::max()).IsValid());
    217   EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
    218   EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
    219   EXPECT_EQ(static_cast<Dst>(1),
    220             CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
    221                                 DstLimits::max()).ValueOrDefault(1));
    222 
    223   // Test the operator combinations.
    224   TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
    225   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
    226   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
    227   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
    228   TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
    229   TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
    230   TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
    231   TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
    232   TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
    233   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
    234   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
    235   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
    236   CheckedNumeric<Dst> checked_dst = 1;
    237   TEST_EXPECTED_VALUE(2, checked_dst += 1);
    238   checked_dst = 1;
    239   TEST_EXPECTED_VALUE(0, checked_dst -= 1);
    240   checked_dst = 1;
    241   TEST_EXPECTED_VALUE(1, checked_dst *= 1);
    242   checked_dst = 1;
    243   TEST_EXPECTED_VALUE(1, checked_dst /= 1);
    244 
    245   // Generic negation.
    246   TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
    247   TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
    248   TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
    249   TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
    250                       -CheckedNumeric<Dst>(DstLimits::max()));
    251 
    252   // Generic absolute value.
    253   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
    254   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
    255   TEST_EXPECTED_VALUE(DstLimits::max(),
    256                       CheckedNumeric<Dst>(DstLimits::max()).Abs());
    257 
    258   // Generic addition.
    259   TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
    260   TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
    261   TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
    262   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    263                          CheckedNumeric<Dst>(DstLimits::min()) + 1);
    264   TEST_EXPECTED_VALIDITY(
    265       RANGE_OVERFLOW, CheckedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
    266 
    267   // Generic subtraction.
    268   TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
    269   TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
    270   TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
    271   TEST_EXPECTED_VALIDITY(RANGE_VALID,
    272                          CheckedNumeric<Dst>(DstLimits::max()) - 1);
    273 
    274   // Generic multiplication.
    275   TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
    276   TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
    277   TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
    278   TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
    279   TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
    280   TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
    281   TEST_EXPECTED_VALIDITY(
    282       RANGE_OVERFLOW, CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
    283 
    284   // Generic division.
    285   TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
    286   TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
    287   TEST_EXPECTED_VALUE(DstLimits::min() / 2,
    288                       CheckedNumeric<Dst>(DstLimits::min()) / 2);
    289   TEST_EXPECTED_VALUE(DstLimits::max() / 2,
    290                       CheckedNumeric<Dst>(DstLimits::max()) / 2);
    291 
    292   TestSpecializedArithmetic<Dst>(dst, line);
    293 }
    294 
    295 // Helper macro to wrap displaying the conversion types and line numbers.
    296 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
    297 
    298 TEST(SafeNumerics, SignedIntegerMath) {
    299   TEST_ARITHMETIC(int8_t);
    300   TEST_ARITHMETIC(int);
    301   TEST_ARITHMETIC(intptr_t);
    302   TEST_ARITHMETIC(intmax_t);
    303 }
    304 
    305 TEST(SafeNumerics, UnsignedIntegerMath) {
    306   TEST_ARITHMETIC(uint8_t);
    307   TEST_ARITHMETIC(unsigned int);
    308   TEST_ARITHMETIC(uintptr_t);
    309   TEST_ARITHMETIC(uintmax_t);
    310 }
    311 
    312 TEST(SafeNumerics, FloatingPointMath) {
    313   TEST_ARITHMETIC(float);
    314   TEST_ARITHMETIC(double);
    315 }
    316 
    317 // Enumerates the five different conversions types we need to test.
    318 enum NumericConversionType {
    319   SIGN_PRESERVING_VALUE_PRESERVING,
    320   SIGN_PRESERVING_NARROW,
    321   SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
    322   SIGN_TO_UNSIGN_NARROW,
    323   UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
    324 };
    325 
    326 // Template covering the different conversion tests.
    327 template <typename Dst, typename Src, NumericConversionType conversion>
    328 struct TestNumericConversion {};
    329 
    330 // EXPECT_EQ wrappers providing specific detail on test failures.
    331 #define TEST_EXPECTED_RANGE(expected, actual)                                  \
    332   EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \
    333       << "Conversion test: " << src << " value " << actual << " to " << dst    \
    334       << " on line " << line;
    335 
    336 template <typename Dst, typename Src>
    337 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
    338   static void Test(const char *dst, const char *src, int line) {
    339     typedef numeric_limits<Src> SrcLimits;
    340     typedef numeric_limits<Dst> DstLimits;
    341                    // Integral to floating.
    342     static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
    343                   // Not floating to integral and...
    344                   (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
    345                    // Same sign, same numeric, source is narrower or same.
    346                    ((SrcLimits::is_signed == DstLimits::is_signed &&
    347                     sizeof(Dst) >= sizeof(Src)) ||
    348                    // Or signed destination and source is smaller
    349                     (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))),
    350                   "Comparison must be sign preserving and value preserving");
    351 
    352     const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
    353     TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst);
    354     if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
    355       if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
    356         // At least twice larger type.
    357         TEST_EXPECTED_VALIDITY(RANGE_VALID, SrcLimits::max() * checked_dst);
    358 
    359       } else {  // Larger, but not at least twice as large.
    360         TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, SrcLimits::max() * checked_dst);
    361         TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst + 1);
    362       }
    363     } else {  // Same width type.
    364       TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + 1);
    365     }
    366 
    367     TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
    368     TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
    369     if (SrcLimits::is_iec559) {
    370       TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
    371       TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
    372       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
    373       TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
    374     } else if (numeric_limits<Src>::is_signed) {
    375       TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
    376       TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
    377     }
    378   }
    379 };
    380 
    381 template <typename Dst, typename Src>
    382 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
    383   static void Test(const char *dst, const char *src, int line) {
    384     typedef numeric_limits<Src> SrcLimits;
    385     typedef numeric_limits<Dst> DstLimits;
    386     static_assert(SrcLimits::is_signed == DstLimits::is_signed,
    387                   "Destination and source sign must be the same");
    388     static_assert(sizeof(Dst) < sizeof(Src) ||
    389                    (DstLimits::is_integer && SrcLimits::is_iec559),
    390                   "Destination must be narrower than source");
    391 
    392     const CheckedNumeric<Dst> checked_dst;
    393     TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max());
    394     TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
    395     TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max());
    396 
    397     TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
    398     TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
    399     if (SrcLimits::is_iec559) {
    400       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
    401       TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
    402       TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
    403       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
    404       TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
    405       if (DstLimits::is_integer) {
    406         if (SrcLimits::digits < DstLimits::digits) {
    407           TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
    408                               static_cast<Src>(DstLimits::max()));
    409         } else {
    410           TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
    411         }
    412         TEST_EXPECTED_RANGE(
    413             RANGE_VALID,
    414             static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
    415         TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
    416       }
    417     } else if (SrcLimits::is_signed) {
    418       TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
    419       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
    420       TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
    421     } else {
    422       TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1));
    423       TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
    424     }
    425   }
    426 };
    427 
    428 template <typename Dst, typename Src>
    429 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
    430   static void Test(const char *dst, const char *src, int line) {
    431     typedef numeric_limits<Src> SrcLimits;
    432     typedef numeric_limits<Dst> DstLimits;
    433     static_assert(sizeof(Dst) >= sizeof(Src),
    434                   "Destination must be equal or wider than source.");
    435     static_assert(SrcLimits::is_signed, "Source must be signed");
    436     static_assert(!DstLimits::is_signed, "Destination must be unsigned");
    437 
    438     const CheckedNumeric<Dst> checked_dst;
    439     TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
    440     TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + static_cast<Src>(-1));
    441     TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max());
    442 
    443     TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
    444     TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
    445     TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
    446     TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
    447   }
    448 };
    449 
    450 template <typename Dst, typename Src>
    451 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
    452   static void Test(const char *dst, const char *src, int line) {
    453     typedef numeric_limits<Src> SrcLimits;
    454     typedef numeric_limits<Dst> DstLimits;
    455     static_assert((DstLimits::is_integer && SrcLimits::is_iec559) ||
    456                    (sizeof(Dst) < sizeof(Src)),
    457                   "Destination must be narrower than source.");
    458     static_assert(SrcLimits::is_signed, "Source must be signed.");
    459     static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
    460 
    461     const CheckedNumeric<Dst> checked_dst;
    462     TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
    463     TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max());
    464     TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + static_cast<Src>(-1));
    465     TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max());
    466 
    467     TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
    468     TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
    469     TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
    470     if (SrcLimits::is_iec559) {
    471       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
    472       TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
    473       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
    474       TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
    475       if (DstLimits::is_integer) {
    476         if (SrcLimits::digits < DstLimits::digits) {
    477           TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
    478                               static_cast<Src>(DstLimits::max()));
    479         } else {
    480           TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
    481         }
    482         TEST_EXPECTED_RANGE(
    483             RANGE_VALID,
    484             static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
    485         TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
    486       }
    487     } else {
    488       TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
    489     }
    490   }
    491 };
    492 
    493 template <typename Dst, typename Src>
    494 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
    495   static void Test(const char *dst, const char *src, int line) {
    496     typedef numeric_limits<Src> SrcLimits;
    497     typedef numeric_limits<Dst> DstLimits;
    498     static_assert(sizeof(Dst) <= sizeof(Src),
    499                   "Destination must be narrower or equal to source.");
    500     static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
    501     static_assert(DstLimits::is_signed, "Destination must be signed.");
    502 
    503     const CheckedNumeric<Dst> checked_dst;
    504     TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
    505     TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max());
    506     TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min());
    507 
    508     TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
    509     TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
    510     TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
    511   }
    512 };
    513 
    514 // Helper macro to wrap displaying the conversion types and line numbers
    515 #define TEST_NUMERIC_CONVERSION(d, s, t) \
    516   TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
    517 
    518 TEST(SafeNumerics, IntMinOperations) {
    519   TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
    520   TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
    521 
    522   TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
    523   TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
    524   TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
    525 
    526   TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
    527 
    528   TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
    529   TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
    530   TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
    531 
    532   TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
    533   TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
    534 }
    535 
    536 TEST(SafeNumerics, IntOperations) {
    537   TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
    538   TEST_NUMERIC_CONVERSION(unsigned int, unsigned int,
    539                           SIGN_PRESERVING_VALUE_PRESERVING);
    540   TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
    541   TEST_NUMERIC_CONVERSION(unsigned int, uint8_t,
    542                           SIGN_PRESERVING_VALUE_PRESERVING);
    543   TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
    544 
    545   TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
    546   TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
    547   TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
    548   TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
    549 
    550   TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
    551   TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
    552 
    553   TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
    554   TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
    555   TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
    556 
    557   TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
    558   TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
    559 }
    560 
    561 TEST(SafeNumerics, IntMaxOperations) {
    562   TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
    563   TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t,
    564                           SIGN_PRESERVING_VALUE_PRESERVING);
    565   TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
    566   TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int,
    567                           SIGN_PRESERVING_VALUE_PRESERVING);
    568   TEST_NUMERIC_CONVERSION(intmax_t, unsigned int,
    569                           SIGN_PRESERVING_VALUE_PRESERVING);
    570   TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
    571 
    572   TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
    573   TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
    574 
    575   TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
    576   TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
    577 
    578   TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
    579   TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
    580 
    581   TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
    582 }
    583 
    584 TEST(SafeNumerics, FloatOperations) {
    585   TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
    586   TEST_NUMERIC_CONVERSION(float, uintmax_t,
    587                           SIGN_PRESERVING_VALUE_PRESERVING);
    588   TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
    589   TEST_NUMERIC_CONVERSION(float, unsigned int,
    590                           SIGN_PRESERVING_VALUE_PRESERVING);
    591 
    592   TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
    593 }
    594 
    595 TEST(SafeNumerics, DoubleOperations) {
    596   TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
    597   TEST_NUMERIC_CONVERSION(double, uintmax_t,
    598                           SIGN_PRESERVING_VALUE_PRESERVING);
    599   TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
    600   TEST_NUMERIC_CONVERSION(double, unsigned int,
    601                           SIGN_PRESERVING_VALUE_PRESERVING);
    602 }
    603 
    604 TEST(SafeNumerics, SizeTOperations) {
    605   TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
    606   TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
    607 }
    608 
    609 TEST(SafeNumerics, CastTests) {
    610 // MSVC catches and warns that we're forcing saturation in these tests.
    611 // Since that's intentional, we need to shut this warning off.
    612 #if defined(COMPILER_MSVC)
    613 #pragma warning(disable : 4756)
    614 #endif
    615 
    616   int small_positive = 1;
    617   int small_negative = -1;
    618   double double_small = 1.0;
    619   double double_large = numeric_limits<double>::max();
    620   double double_infinity = numeric_limits<float>::infinity();
    621   double double_large_int = numeric_limits<int>::max();
    622   double double_small_int = numeric_limits<int>::min();
    623 
    624   // Just test that the casts compile, since the other tests cover logic.
    625   EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
    626   EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
    627   EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
    628   EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
    629   EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
    630   EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
    631   EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
    632 
    633   EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
    634   EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
    635   EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
    636 
    637   EXPECT_TRUE(IsValueNegative(-1));
    638   EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min()));
    639   EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min()));
    640   EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max()));
    641   EXPECT_FALSE(IsValueNegative(0));
    642   EXPECT_FALSE(IsValueNegative(1));
    643   EXPECT_FALSE(IsValueNegative(0u));
    644   EXPECT_FALSE(IsValueNegative(1u));
    645   EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
    646   EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
    647   EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
    648 
    649   // These casts and coercions will fail to compile:
    650   // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
    651   // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
    652   // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
    653   // EXPECT_EQ(1, StrictNumeric<size_t>(1U));
    654 
    655   // Test various saturation corner cases.
    656   EXPECT_EQ(saturated_cast<int>(small_negative),
    657             static_cast<int>(small_negative));
    658   EXPECT_EQ(saturated_cast<int>(small_positive),
    659             static_cast<int>(small_positive));
    660   EXPECT_EQ(saturated_cast<unsigned>(small_negative),
    661             static_cast<unsigned>(0));
    662   EXPECT_EQ(saturated_cast<int>(double_small),
    663             static_cast<int>(double_small));
    664   EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
    665   EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
    666   EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
    667   EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int));
    668   EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
    669 
    670   float not_a_number = std::numeric_limits<float>::infinity() -
    671                        std::numeric_limits<float>::infinity();
    672   EXPECT_TRUE(std::isnan(not_a_number));
    673   EXPECT_EQ(0, saturated_cast<int>(not_a_number));
    674 }
    675 
    676 #if GTEST_HAS_DEATH_TEST
    677 
    678 TEST(SafeNumerics, SaturatedCastChecks) {
    679   float not_a_number = std::numeric_limits<float>::infinity() -
    680                        std::numeric_limits<float>::infinity();
    681   EXPECT_TRUE(std::isnan(not_a_number));
    682   EXPECT_DEATH((saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>(
    683       not_a_number)), "");
    684 }
    685 
    686 #endif  // GTEST_HAS_DEATH_TEST
    687 
    688 TEST(SafeNumerics, IsValueInRangeForNumericType) {
    689   EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
    690   EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
    691   EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
    692   EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
    693   EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
    694   EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
    695   EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
    696   EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
    697   EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
    698       std::numeric_limits<int32_t>::min()));
    699   EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
    700       std::numeric_limits<int64_t>::min()));
    701 
    702   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
    703   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
    704   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
    705   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
    706   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
    707   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
    708   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
    709   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
    710   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
    711   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
    712   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
    713   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
    714       std::numeric_limits<int32_t>::min()));
    715   EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
    716       static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
    717   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
    718       static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1));
    719   EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
    720       std::numeric_limits<int64_t>::min()));
    721 
    722   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
    723   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
    724   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
    725   EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
    726   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
    727   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
    728   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
    729   EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
    730   EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
    731       std::numeric_limits<int32_t>::min()));
    732   EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
    733   EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
    734       std::numeric_limits<int64_t>::min()));
    735 
    736   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
    737   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
    738   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
    739   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
    740   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
    741   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
    742   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
    743   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
    744   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
    745   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
    746   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
    747   EXPECT_TRUE(
    748       IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
    749   EXPECT_TRUE(
    750       IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
    751   EXPECT_FALSE(
    752       IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
    753   EXPECT_FALSE(
    754       IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
    755   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
    756       std::numeric_limits<int32_t>::min()));
    757   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
    758       static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
    759   EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
    760       std::numeric_limits<int64_t>::min()));
    761 }
    762 
    763 TEST(SafeNumerics, CompoundNumericOperations) {
    764   CheckedNumeric<int> a = 1;
    765   CheckedNumeric<int> b = 2;
    766   CheckedNumeric<int> c = 3;
    767   CheckedNumeric<int> d = 4;
    768   a += b;
    769   EXPECT_EQ(3, a.ValueOrDie());
    770   a -= c;
    771   EXPECT_EQ(0, a.ValueOrDie());
    772   d /= b;
    773   EXPECT_EQ(2, d.ValueOrDie());
    774   d *= d;
    775   EXPECT_EQ(4, d.ValueOrDie());
    776 
    777   CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
    778   EXPECT_TRUE(too_large.IsValid());
    779   too_large += d;
    780   EXPECT_FALSE(too_large.IsValid());
    781   too_large -= d;
    782   EXPECT_FALSE(too_large.IsValid());
    783   too_large /= d;
    784   EXPECT_FALSE(too_large.IsValid());
    785 }
    786