Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: base/numerics/safe_numerics_unittest.cc

Issue 2510973002: Add support for CheckedNumeric bitshift operators (Closed)
Patch Set: format Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/numerics/safe_math_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « base/numerics/safe_math_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698