| 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 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 using base::StrictNumeric; | 28 using base::StrictNumeric; |
| 29 using base::saturated_cast; | 29 using base::saturated_cast; |
| 30 using base::strict_cast; | 30 using base::strict_cast; |
| 31 using base::internal::MaxExponent; | 31 using base::internal::MaxExponent; |
| 32 using base::internal::RANGE_VALID; | 32 using base::internal::RANGE_VALID; |
| 33 using base::internal::RANGE_INVALID; | 33 using base::internal::RANGE_INVALID; |
| 34 using base::internal::RANGE_OVERFLOW; | 34 using base::internal::RANGE_OVERFLOW; |
| 35 using base::internal::RANGE_UNDERFLOW; | 35 using base::internal::RANGE_UNDERFLOW; |
| 36 using base::internal::SignedIntegerForSize; | 36 using base::internal::SignedIntegerForSize; |
| 37 | 37 |
| 38 // These tests deliberately cause arithmetic overflows. If the compiler is | 38 // These tests deliberately cause arithmetic boundary errors. If the compiler is |
| 39 // aggressive enough, it can const fold these overflows. Disable warnings about | 39 // aggressive enough, it can const detect these errors, so we disable warnings. |
| 40 // overflows for const expressions. | |
| 41 #if defined(OS_WIN) | 40 #if defined(OS_WIN) |
| 42 #pragma warning(disable:4756) | 41 #pragma warning(disable : 4756) // Arithmetic overflow. |
| 42 #pragma warning(disable : 4293) // Invalid shift. |
| 43 #endif | 43 #endif |
| 44 | 44 |
| 45 // This is a helper function for finding the maximum value in Src that can be | 45 // This is a helper function for finding the maximum value in Src that can be |
| 46 // wholy represented as the destination floating-point type. | 46 // wholy represented as the destination floating-point type. |
| 47 template <typename Dst, typename Src> | 47 template <typename Dst, typename Src> |
| 48 Dst GetMaxConvertibleToFloat() { | 48 Dst GetMaxConvertibleToFloat() { |
| 49 typedef numeric_limits<Dst> DstLimits; | 49 typedef numeric_limits<Dst> DstLimits; |
| 50 typedef numeric_limits<Src> SrcLimits; | 50 typedef numeric_limits<Src> SrcLimits; |
| 51 static_assert(SrcLimits::is_specialized, "Source must be numeric."); | 51 static_assert(SrcLimits::is_specialized, "Source must be numeric."); |
| 52 static_assert(DstLimits::is_specialized, "Destination must be numeric."); | 52 static_assert(DstLimits::is_specialized, "Destination must be numeric."); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); | 116 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); |
| 117 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); | 117 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); |
| 118 // Test all the different modulus combinations. | 118 // Test all the different modulus combinations. |
| 119 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); | 119 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); |
| 120 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); | 120 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); |
| 121 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 121 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 122 CheckedNumeric<Dst> checked_dst = 1; | 122 CheckedNumeric<Dst> checked_dst = 1; |
| 123 TEST_EXPECTED_VALUE(0, checked_dst %= 1); | 123 TEST_EXPECTED_VALUE(0, checked_dst %= 1); |
| 124 // Test that div by 0 is avoided but returns invalid result. | 124 // Test that div by 0 is avoided but returns invalid result. |
| 125 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0); | 125 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0); |
| 126 // Test bit shifts. |
| 127 volatile Dst negative_one = -1; |
| 128 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one); |
| 129 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << (sizeof(Dst) * CHAR_BIT - 1)); |
| 130 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0) << (sizeof(Dst) * CHAR_BIT)); |
| 131 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1); |
| 132 TEST_EXPECTED_VALUE(static_cast<Dst>(1) << (sizeof(Dst) * CHAR_BIT - 2), |
| 133 CheckedNumeric<Dst>(1) << (sizeof(Dst) * CHAR_BIT - 2)); |
| 134 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) |
| 135 << (sizeof(Dst) * CHAR_BIT - 1)); |
| 136 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0); |
| 137 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1); |
| 138 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> (sizeof(Dst) * CHAR_BIT)); |
| 139 TEST_EXPECTED_VALUE(0, |
| 140 CheckedNumeric<Dst>(1) >> (sizeof(Dst) * CHAR_BIT - 1)); |
| 141 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one); |
| 126 } | 142 } |
| 127 | 143 |
| 128 // Unsigned integer arithmetic. | 144 // Unsigned integer arithmetic. |
| 129 template <typename Dst> | 145 template <typename Dst> |
| 130 static void TestSpecializedArithmetic( | 146 static void TestSpecializedArithmetic( |
| 131 const char* dst, | 147 const char* dst, |
| 132 int line, | 148 int line, |
| 133 typename std::enable_if<numeric_limits<Dst>::is_integer && | 149 typename std::enable_if<numeric_limits<Dst>::is_integer && |
| 134 !numeric_limits<Dst>::is_signed, | 150 !numeric_limits<Dst>::is_signed, |
| 135 int>::type = 0) { | 151 int>::type = 0) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 153 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); | 169 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); |
| 154 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); | 170 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); |
| 155 // Test all the different modulus combinations. | 171 // Test all the different modulus combinations. |
| 156 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); | 172 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); |
| 157 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); | 173 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); |
| 158 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 174 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 159 CheckedNumeric<Dst> checked_dst = 1; | 175 CheckedNumeric<Dst> checked_dst = 1; |
| 160 TEST_EXPECTED_VALUE(0, checked_dst %= 1); | 176 TEST_EXPECTED_VALUE(0, checked_dst %= 1); |
| 161 // Test that div by 0 is avoided but returns invalid result. | 177 // Test that div by 0 is avoided but returns invalid result. |
| 162 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0); | 178 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0); |
| 179 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << (sizeof(Dst) * CHAR_BIT)); |
| 180 // Test bit shifts. |
| 181 volatile int negative_one = -1; |
| 182 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one); |
| 183 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << (sizeof(Dst) * CHAR_BIT)); |
| 184 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0) << (sizeof(Dst) * CHAR_BIT)); |
| 185 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1); |
| 186 TEST_EXPECTED_VALUE(static_cast<Dst>(1) << (sizeof(Dst) * CHAR_BIT - 1), |
| 187 CheckedNumeric<Dst>(1) << (sizeof(Dst) * CHAR_BIT - 1)); |
| 188 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0); |
| 189 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1); |
| 190 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> (sizeof(Dst) * CHAR_BIT)); |
| 191 TEST_EXPECTED_VALUE(0, |
| 192 CheckedNumeric<Dst>(1) >> (sizeof(Dst) * CHAR_BIT - 1)); |
| 193 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one); |
| 163 } | 194 } |
| 164 | 195 |
| 165 // Floating point arithmetic. | 196 // Floating point arithmetic. |
| 166 template <typename Dst> | 197 template <typename Dst> |
| 167 void TestSpecializedArithmetic( | 198 void TestSpecializedArithmetic( |
| 168 const char* dst, | 199 const char* dst, |
| 169 int line, | 200 int line, |
| 170 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { | 201 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { |
| 171 typedef numeric_limits<Dst> DstLimits; | 202 typedef numeric_limits<Dst> DstLimits; |
| 172 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min())); | 203 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min())); |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 | 800 |
| 770 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); | 801 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); |
| 771 EXPECT_TRUE(too_large.IsValid()); | 802 EXPECT_TRUE(too_large.IsValid()); |
| 772 too_large += d; | 803 too_large += d; |
| 773 EXPECT_FALSE(too_large.IsValid()); | 804 EXPECT_FALSE(too_large.IsValid()); |
| 774 too_large -= d; | 805 too_large -= d; |
| 775 EXPECT_FALSE(too_large.IsValid()); | 806 EXPECT_FALSE(too_large.IsValid()); |
| 776 too_large /= d; | 807 too_large /= d; |
| 777 EXPECT_FALSE(too_large.IsValid()); | 808 EXPECT_FALSE(too_large.IsValid()); |
| 778 } | 809 } |
| OLD | NEW |