• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
GetMaxConvertibleToFloat()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>
TestSpecializedArithmetic(const char * dst,int line,typename std::enable_if<numeric_limits<Dst>::is_integer && numeric_limits<Dst>::is_signed,int>::type=0)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>
TestSpecializedArithmetic(const char * dst,int line,typename std::enable_if<numeric_limits<Dst>::is_integer &&!numeric_limits<Dst>::is_signed,int>::type=0)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>
TestSpecializedArithmetic(const char * dst,int line,typename std::enable_if<numeric_limits<Dst>::is_iec559,int>::type=0)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>
TestArithmetic(const char * dst,int line)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 
TEST(SafeNumerics,SignedIntegerMath)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 
TEST(SafeNumerics,UnsignedIntegerMath)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 
TEST(SafeNumerics,FloatingPointMath)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> {
TestTestNumericConversion338   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> {
TestTestNumericConversion383   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> {
TestTestNumericConversion430   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> {
TestTestNumericConversion452   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> {
TestTestNumericConversion495   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 
TEST(SafeNumerics,IntMinOperations)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 
TEST(SafeNumerics,IntOperations)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 
TEST(SafeNumerics,IntMaxOperations)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 
TEST(SafeNumerics,FloatOperations)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 
TEST(SafeNumerics,DoubleOperations)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 
TEST(SafeNumerics,SizeTOperations)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 
TEST(SafeNumerics,CastTests)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 
TEST(SafeNumerics,SaturatedCastChecks)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 
TEST(SafeNumerics,IsValueInRangeForNumericType)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 
TEST(SafeNumerics,CompoundNumericOperations)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