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 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <type_traits> | 9 #include <type_traits> |
| 10 | 10 |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/numerics/safe_conversions.h" | 12 #include "base/numerics/safe_conversions.h" |
| 13 #include "base/numerics/safe_math.h" | 13 #include "base/numerics/safe_math.h" |
| 14 #include "base/test/gtest_util.h" | 14 #include "base/test/gtest_util.h" |
| 15 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) | 18 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) |
| 19 #include <mmintrin.h> | 19 #include <mmintrin.h> |
| 20 #endif | 20 #endif |
| 21 | 21 |
| 22 using std::numeric_limits; | 22 using std::numeric_limits; |
| 23 using base::CheckedNumeric; | 23 using base::CheckedNumeric; |
| 24 using base::CheckNum; | |
| 25 using base::CheckAdd; | |
| 26 using base::CheckSub; | |
| 27 using base::CheckMul; | |
| 28 using base::CheckDiv; | |
| 29 using base::CheckMod; | |
| 30 using base::CheckLsh; | |
| 31 using base::CheckRsh; | |
| 24 using base::checked_cast; | 32 using base::checked_cast; |
| 25 using base::IsValueInRangeForNumericType; | 33 using base::IsValueInRangeForNumericType; |
| 26 using base::IsValueNegative; | 34 using base::IsValueNegative; |
| 27 using base::SizeT; | 35 using base::SizeT; |
| 28 using base::StrictNumeric; | 36 using base::StrictNumeric; |
| 29 using base::saturated_cast; | 37 using base::saturated_cast; |
| 30 using base::strict_cast; | 38 using base::strict_cast; |
| 31 using base::internal::MaxExponent; | 39 using base::internal::MaxExponent; |
| 32 using base::internal::RANGE_VALID; | 40 using base::internal::RANGE_VALID; |
| 33 using base::internal::RANGE_INVALID; | 41 using base::internal::RANGE_INVALID; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 U GetNumericValueForTest(const CheckedNumeric<U>& src) { | 76 U GetNumericValueForTest(const CheckedNumeric<U>& src) { |
| 69 return src.state_.value(); | 77 return src.state_.value(); |
| 70 } | 78 } |
| 71 } // namespace internal. | 79 } // namespace internal. |
| 72 } // namespace base. | 80 } // namespace base. |
| 73 | 81 |
| 74 using base::internal::GetNumericValueForTest; | 82 using base::internal::GetNumericValueForTest; |
| 75 | 83 |
| 76 // Helper macros to wrap displaying the conversion types and line numbers. | 84 // Helper macros to wrap displaying the conversion types and line numbers. |
| 77 #define TEST_EXPECTED_VALIDITY(expected, actual) \ | 85 #define TEST_EXPECTED_VALIDITY(expected, actual) \ |
| 78 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \ | 86 EXPECT_EQ(expected, (actual).Cast<Dst>().IsValid()) \ |
| 79 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \ | 87 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \ |
| 80 << dst << " on line " << line | 88 << dst << " on line " << line |
| 81 | 89 |
| 82 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) | 90 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) |
| 83 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) | 91 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) |
| 84 | 92 |
| 85 #define TEST_EXPECTED_VALUE(expected, actual) \ | 93 #define TEST_EXPECTED_VALUE(expected, actual) \ |
| 86 EXPECT_EQ(static_cast<Dst>(expected), \ | 94 EXPECT_EQ(static_cast<Dst>(expected), (actual).Cast<Dst>().ValueOrDie()) \ |
| 87 CheckedNumeric<Dst>(actual).ValueOrDie()) \ | |
| 88 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \ | 95 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \ |
| 89 << dst << " on line " << line | 96 << dst << " on line " << line |
| 90 | 97 |
| 91 // Signed integer arithmetic. | 98 // Signed integer arithmetic. |
| 92 template <typename Dst> | 99 template <typename Dst> |
| 93 static void TestSpecializedArithmetic( | 100 static void TestSpecializedArithmetic( |
| 94 const char* dst, | 101 const char* dst, |
| 95 int line, | 102 int line, |
| 96 typename std::enable_if<numeric_limits<Dst>::is_integer && | 103 typename std::enable_if<numeric_limits<Dst>::is_integer && |
| 97 numeric_limits<Dst>::is_signed, | 104 numeric_limits<Dst>::is_signed, |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 811 | 818 |
| 812 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); | 819 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); |
| 813 EXPECT_TRUE(too_large.IsValid()); | 820 EXPECT_TRUE(too_large.IsValid()); |
| 814 too_large += d; | 821 too_large += d; |
| 815 EXPECT_FALSE(too_large.IsValid()); | 822 EXPECT_FALSE(too_large.IsValid()); |
| 816 too_large -= d; | 823 too_large -= d; |
| 817 EXPECT_FALSE(too_large.IsValid()); | 824 EXPECT_FALSE(too_large.IsValid()); |
| 818 too_large /= d; | 825 too_large /= d; |
| 819 EXPECT_FALSE(too_large.IsValid()); | 826 EXPECT_FALSE(too_large.IsValid()); |
| 820 } | 827 } |
| 828 | |
| 829 TEST(SafeNumerics, VariadicNumericOperations) { | |
| 830 auto a = CheckAdd(1, 2UL, CheckNum(3LL), 4).ValueOrDie(); | |
| 831 EXPECT_EQ(static_cast<decltype(a)>(10), a); | |
| 832 auto b = CheckSub(CheckNum(20.0), 2UL, 4).ValueOrDie(); | |
| 833 EXPECT_EQ(static_cast<decltype(b)>(14.0), b); | |
| 834 auto c = CheckMul(20.0, CheckNum(1), 5, 3UL).ValueOrDie(); | |
| 835 EXPECT_EQ(static_cast<decltype(c)>(300.0), c); | |
| 836 auto d = CheckDiv(20.0, 2.0, CheckNum(5LL), -4).ValueOrDie(); | |
| 837 EXPECT_EQ(static_cast<decltype(d)>(-.5), d); | |
| 838 auto e = CheckMod(CheckNum(20), 3).ValueOrDie(); | |
| 839 EXPECT_EQ(static_cast<decltype(e)>(2), e); | |
| 840 auto f = CheckLsh(1, CheckNum(2)).ValueOrDie(); | |
| 841 EXPECT_EQ(static_cast<decltype(f)>(4), f); | |
| 842 auto g = CheckRsh(4, CheckNum(2)).ValueOrDie(); | |
| 843 EXPECT_EQ(static_cast<decltype(g)>(1), g); | |
| 844 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); | |
| 845 EXPECT_EQ(static_cast<decltype(h)>(1), h); | |
|
Tom Sepez
2016/11/23 21:37:25
can we add a test that CheckAdd<int16_t>(0x10000,
| |
| 846 } | |
| OLD | NEW |