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