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 |