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