OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) | 5 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) |
6 #include <mmintrin.h> | 6 #include <mmintrin.h> |
7 #endif | 7 #endif |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <limits> | 10 #include <limits> |
11 | 11 |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/numerics/safe_conversions.h" | 13 #include "base/numerics/safe_conversions.h" |
14 #include "base/numerics/safe_math.h" | 14 #include "base/numerics/safe_math.h" |
15 #include "base/template_util.h" | 15 #include "base/template_util.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 using std::numeric_limits; | 18 using std::numeric_limits; |
19 using base::CheckedNumeric; | 19 using base::CheckedNumeric; |
20 using base::checked_cast; | 20 using base::checked_cast; |
| 21 using base::IsValueInRangeForNumericType; |
21 using base::SizeT; | 22 using base::SizeT; |
22 using base::StrictNumeric; | 23 using base::StrictNumeric; |
23 using base::saturated_cast; | 24 using base::saturated_cast; |
24 using base::strict_cast; | 25 using base::strict_cast; |
25 using base::internal::MaxExponent; | 26 using base::internal::MaxExponent; |
26 using base::internal::RANGE_VALID; | 27 using base::internal::RANGE_VALID; |
27 using base::internal::RANGE_INVALID; | 28 using base::internal::RANGE_INVALID; |
28 using base::internal::RANGE_OVERFLOW; | 29 using base::internal::RANGE_OVERFLOW; |
29 using base::internal::RANGE_UNDERFLOW; | 30 using base::internal::RANGE_UNDERFLOW; |
30 using base::enable_if; | 31 using base::enable_if; |
31 | 32 |
32 // These tests deliberately cause arithmetic overflows. If the compiler is | 33 // These tests deliberately cause arithmetic overflows. If the compiler is |
33 // aggressive enough, it can const fold these overflows. Disable warnings about | 34 // aggressive enough, it can const fold these overflows. Disable warnings about |
34 // overflows for const expressions. | 35 // overflows for const expressions. |
35 #if defined(OS_WIN) | 36 #if defined(OS_WIN) |
36 #pragma warning(disable:4756) | 37 #pragma warning(disable:4756) |
37 #endif | 38 #endif |
38 | 39 |
| 40 // This is a helper function for finding the maximum value in Src that can be |
| 41 // wholy represented as the destination floating-point type. |
| 42 template <typename Dst, typename Src> |
| 43 Dst GetMaxConvertibleToFloat() { |
| 44 typedef numeric_limits<Dst> DstLimits; |
| 45 typedef numeric_limits<Src> SrcLimits; |
| 46 static_assert(SrcLimits::is_specialized, "Source must be numeric."); |
| 47 static_assert(DstLimits::is_specialized, "Destination must be numeric."); |
| 48 CHECK(DstLimits::is_iec559); |
| 49 |
| 50 if (SrcLimits::digits <= DstLimits::digits && |
| 51 MaxExponent<Src>::value <= MaxExponent<Dst>::value) |
| 52 return SrcLimits::max(); |
| 53 Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0); |
| 54 while (max != static_cast<Src>(static_cast<Dst>(max))) { |
| 55 max /= 2; |
| 56 } |
| 57 return static_cast<Dst>(max); |
| 58 } |
| 59 |
39 // Helper macros to wrap displaying the conversion types and line numbers. | 60 // Helper macros to wrap displaying the conversion types and line numbers. |
40 #define TEST_EXPECTED_VALIDITY(expected, actual) \ | 61 #define TEST_EXPECTED_VALIDITY(expected, actual) \ |
41 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \ | 62 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \ |
42 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ | 63 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ |
43 << " on line " << line; | 64 << " on line " << line; |
44 | 65 |
45 #define TEST_EXPECTED_VALUE(expected, actual) \ | 66 #define TEST_EXPECTED_VALUE(expected, actual) \ |
46 EXPECT_EQ(static_cast<Dst>(expected), \ | 67 EXPECT_EQ(static_cast<Dst>(expected), \ |
47 CheckedNumeric<Dst>(actual).ValueUnsafe()) \ | 68 CheckedNumeric<Dst>(actual).ValueUnsafe()) \ |
48 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ | 69 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); | 384 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); |
364 | 385 |
365 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 386 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
366 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 387 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
367 if (SrcLimits::is_iec559) { | 388 if (SrcLimits::is_iec559) { |
368 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 389 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
369 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 390 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
370 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 391 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
371 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 392 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
372 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 393 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 394 if (DstLimits::is_integer) { |
| 395 if (SrcLimits::digits < DstLimits::digits) { |
| 396 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, |
| 397 static_cast<Src>(DstLimits::max())); |
| 398 } else { |
| 399 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); |
| 400 } |
| 401 TEST_EXPECTED_RANGE( |
| 402 RANGE_VALID, |
| 403 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); |
| 404 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); |
| 405 } |
373 } else if (SrcLimits::is_signed) { | 406 } else if (SrcLimits::is_signed) { |
374 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); | 407 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); |
375 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 408 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
376 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 409 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
377 } else { | 410 } else { |
378 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); | 411 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); |
379 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 412 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
380 } | 413 } |
381 } | 414 } |
382 }; | 415 }; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); | 454 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); |
422 | 455 |
423 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 456 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
424 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 457 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
425 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); | 458 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); |
426 if (SrcLimits::is_iec559) { | 459 if (SrcLimits::is_iec559) { |
427 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 460 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
428 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 461 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
429 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 462 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
430 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 463 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 464 if (DstLimits::is_integer) { |
| 465 if (SrcLimits::digits < DstLimits::digits) { |
| 466 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, |
| 467 static_cast<Src>(DstLimits::max())); |
| 468 } else { |
| 469 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); |
| 470 } |
| 471 TEST_EXPECTED_RANGE( |
| 472 RANGE_VALID, |
| 473 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); |
| 474 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); |
| 475 } |
431 } else { | 476 } else { |
432 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 477 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
433 } | 478 } |
434 } | 479 } |
435 }; | 480 }; |
436 | 481 |
437 template <typename Dst, typename Src> | 482 template <typename Dst, typename Src> |
438 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { | 483 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { |
439 static void Test(const char *dst, const char *src, int line) { | 484 static void Test(const char *dst, const char *src, int line) { |
440 typedef numeric_limits<Src> SrcLimits; | 485 typedef numeric_limits<Src> SrcLimits; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 static_cast<unsigned>(0)); | 638 static_cast<unsigned>(0)); |
594 EXPECT_EQ(saturated_cast<int>(double_small), | 639 EXPECT_EQ(saturated_cast<int>(double_small), |
595 static_cast<int>(double_small)); | 640 static_cast<int>(double_small)); |
596 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); | 641 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); |
597 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); | 642 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); |
598 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); | 643 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); |
599 EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int)); | 644 EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int)); |
600 EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int)); | 645 EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int)); |
601 } | 646 } |
602 | 647 |
| 648 TEST(SafeNumerics, IsValueInRangeForNumericType) { |
| 649 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0)); |
| 650 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1)); |
| 651 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2)); |
| 652 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1)); |
| 653 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu)); |
| 654 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff))); |
| 655 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000))); |
| 656 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001))); |
| 657 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>( |
| 658 std::numeric_limits<int32_t>::min())); |
| 659 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>( |
| 660 std::numeric_limits<int64_t>::min())); |
| 661 |
| 662 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0)); |
| 663 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1)); |
| 664 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2)); |
| 665 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1)); |
| 666 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff)); |
| 667 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu)); |
| 668 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u)); |
| 669 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu)); |
| 670 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000))); |
| 671 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff))); |
| 672 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000))); |
| 673 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>( |
| 674 std::numeric_limits<int32_t>::min())); |
| 675 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>( |
| 676 implicit_cast<int64_t>(std::numeric_limits<int32_t>::min()))); |
| 677 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>( |
| 678 implicit_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1)); |
| 679 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>( |
| 680 std::numeric_limits<int64_t>::min())); |
| 681 |
| 682 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0)); |
| 683 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1)); |
| 684 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2)); |
| 685 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1)); |
| 686 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu)); |
| 687 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff))); |
| 688 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000))); |
| 689 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001))); |
| 690 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>( |
| 691 std::numeric_limits<int32_t>::min())); |
| 692 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1))); |
| 693 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>( |
| 694 std::numeric_limits<int64_t>::min())); |
| 695 |
| 696 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0)); |
| 697 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1)); |
| 698 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2)); |
| 699 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1)); |
| 700 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff)); |
| 701 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu)); |
| 702 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u)); |
| 703 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu)); |
| 704 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000))); |
| 705 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff))); |
| 706 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000))); |
| 707 EXPECT_TRUE( |
| 708 IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff))); |
| 709 EXPECT_TRUE( |
| 710 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff))); |
| 711 EXPECT_FALSE( |
| 712 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000))); |
| 713 EXPECT_FALSE( |
| 714 IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff))); |
| 715 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( |
| 716 std::numeric_limits<int32_t>::min())); |
| 717 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( |
| 718 implicit_cast<int64_t>(std::numeric_limits<int32_t>::min()))); |
| 719 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( |
| 720 std::numeric_limits<int64_t>::min())); |
| 721 } |
OLD | NEW |