Chromium Code Reviews| 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; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); | 364 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); |
| 364 | 365 |
| 365 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 366 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
| 366 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 367 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 367 if (SrcLimits::is_iec559) { | 368 if (SrcLimits::is_iec559) { |
| 368 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 369 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
| 369 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 370 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
| 370 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 371 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
| 371 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 372 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
| 372 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 373 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 374 if (!DstLimits::is_iec559) { | |
| 375 if (SrcLimits::digits < DstLimits::digits) { | |
| 376 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, | |
| 377 static_cast<Src>(DstLimits::max())); | |
| 378 } else { | |
| 379 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); | |
| 380 } | |
| 381 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); | |
| 382 } | |
| 373 } else if (SrcLimits::is_signed) { | 383 } else if (SrcLimits::is_signed) { |
| 374 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); | 384 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); |
| 375 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 385 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
| 376 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 386 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
| 377 } else { | 387 } else { |
| 378 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); | 388 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); |
| 379 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 389 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
| 380 } | 390 } |
| 381 } | 391 } |
| 382 }; | 392 }; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); | 431 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); |
| 422 | 432 |
| 423 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 433 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
| 424 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 434 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 425 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); | 435 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); |
| 426 if (SrcLimits::is_iec559) { | 436 if (SrcLimits::is_iec559) { |
| 427 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 437 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
| 428 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 438 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
| 429 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 439 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
| 430 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 440 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 441 if (!DstLimits::is_iec559) { | |
| 442 if (SrcLimits::digits < DstLimits::digits) { | |
| 443 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, | |
| 444 static_cast<Src>(DstLimits::max())); | |
| 445 } else { | |
| 446 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); | |
| 447 } | |
| 448 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); | |
| 449 } | |
| 431 } else { | 450 } else { |
| 432 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 451 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
| 433 } | 452 } |
| 434 } | 453 } |
| 435 }; | 454 }; |
| 436 | 455 |
| 437 template <typename Dst, typename Src> | 456 template <typename Dst, typename Src> |
| 438 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { | 457 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { |
| 439 static void Test(const char *dst, const char *src, int line) { | 458 static void Test(const char *dst, const char *src, int line) { |
| 440 typedef numeric_limits<Src> SrcLimits; | 459 typedef numeric_limits<Src> SrcLimits; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 static_cast<unsigned>(0)); | 612 static_cast<unsigned>(0)); |
| 594 EXPECT_EQ(saturated_cast<int>(double_small), | 613 EXPECT_EQ(saturated_cast<int>(double_small), |
| 595 static_cast<int>(double_small)); | 614 static_cast<int>(double_small)); |
| 596 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); | 615 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); |
| 597 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); | 616 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); |
| 598 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); | 617 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); |
| 599 EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int)); | 618 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)); | 619 EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int)); |
| 601 } | 620 } |
| 602 | 621 |
| 622 TEST(SafeNumerics, IsValueInRangeForNumericType) { | |
|
brucedawson
2015/09/11 23:23:27
An additional class of tests would be to generate
jschuh
2015/09/12 00:43:12
Yup. In a previous iteration I had to add some pla
| |
| 623 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0)); | |
| 624 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1)); | |
| 625 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2)); | |
| 626 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1)); | |
| 627 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu)); | |
| 628 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff))); | |
| 629 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000))); | |
| 630 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001))); | |
| 631 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>( | |
| 632 std::numeric_limits<int32_t>::min())); | |
| 633 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>( | |
| 634 std::numeric_limits<int64_t>::min())); | |
| 635 | |
| 636 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0)); | |
| 637 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1)); | |
| 638 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2)); | |
| 639 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1)); | |
| 640 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff)); | |
| 641 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu)); | |
| 642 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u)); | |
| 643 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu)); | |
| 644 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000))); | |
| 645 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff))); | |
| 646 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000))); | |
| 647 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>( | |
| 648 std::numeric_limits<int32_t>::min())); | |
| 649 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>( | |
| 650 implicit_cast<int64_t>(std::numeric_limits<int32_t>::min()))); | |
| 651 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>( | |
| 652 implicit_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1)); | |
| 653 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>( | |
| 654 std::numeric_limits<int64_t>::min())); | |
| 655 | |
| 656 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0)); | |
| 657 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1)); | |
| 658 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2)); | |
| 659 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1)); | |
| 660 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu)); | |
| 661 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff))); | |
| 662 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000))); | |
| 663 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001))); | |
| 664 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>( | |
| 665 std::numeric_limits<int32_t>::min())); | |
| 666 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1))); | |
| 667 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>( | |
| 668 std::numeric_limits<int64_t>::min())); | |
| 669 | |
| 670 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0)); | |
| 671 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1)); | |
| 672 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2)); | |
| 673 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1)); | |
| 674 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff)); | |
| 675 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu)); | |
| 676 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u)); | |
| 677 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu)); | |
| 678 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000))); | |
| 679 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff))); | |
| 680 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000))); | |
| 681 EXPECT_TRUE( | |
| 682 IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff))); | |
| 683 EXPECT_TRUE( | |
| 684 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff))); | |
| 685 EXPECT_FALSE( | |
| 686 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000))); | |
| 687 EXPECT_FALSE( | |
| 688 IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff))); | |
| 689 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( | |
| 690 std::numeric_limits<int32_t>::min())); | |
| 691 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( | |
| 692 implicit_cast<int64_t>(std::numeric_limits<int32_t>::min()))); | |
| 693 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( | |
| 694 std::numeric_limits<int64_t>::min())); | |
| 695 } | |
| OLD | NEW |