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