blob: b804d36f7af1e034928341257c81082d1f3a43d3 [file] [log] [blame]
[email protected]c1c090d32013-01-16 23:34:041// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avi9b6f42932015-12-26 22:15:145#include <stddef.h>
[email protected]4efb2c32014-01-16 06:57:256#include <stdint.h>
7
8#include <limits>
vmpstr98a2fad2015-11-30 20:15:179#include <type_traits>
[email protected]4efb2c32014-01-16 06:57:2510
11#include "base/compiler_specific.h"
[email protected]5bfecbc2014-02-27 13:49:0412#include "base/numerics/safe_conversions.h"
13#include "base/numerics/safe_math.h"
gab190f7542016-08-01 20:03:4114#include "base/test/gtest_util.h"
avi9b6f42932015-12-26 22:15:1415#include "build/build_config.h"
[email protected]4efb2c32014-01-16 06:57:2516#include "testing/gtest/include/gtest/gtest.h"
17
avi9b6f42932015-12-26 22:15:1418#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
19#include <mmintrin.h>
20#endif
21
[email protected]5bfecbc2014-02-27 13:49:0422using std::numeric_limits;
23using base::CheckedNumeric;
24using base::checked_cast;
jschuhfafe0712015-09-14 20:21:2425using base::IsValueInRangeForNumericType;
jschuh07345e62015-09-22 22:13:3626using base::IsValueNegative;
jschuh4bf22c6d2015-05-28 02:29:2527using base::SizeT;
28using base::StrictNumeric;
[email protected]5bfecbc2014-02-27 13:49:0429using base::saturated_cast;
jschuh4bf22c6d2015-05-28 02:29:2530using base::strict_cast;
[email protected]5bfecbc2014-02-27 13:49:0431using base::internal::MaxExponent;
32using base::internal::RANGE_VALID;
33using base::internal::RANGE_INVALID;
34using base::internal::RANGE_OVERFLOW;
35using base::internal::RANGE_UNDERFLOW;
jschuheaf375f2015-09-17 01:04:2836using base::internal::SignedIntegerForSize;
[email protected]5bfecbc2014-02-27 13:49:0437
[email protected]b6bf5c322014-08-09 05:24:0238// These tests deliberately cause arithmetic overflows. If the compiler is
39// aggressive enough, it can const fold these overflows. Disable warnings about
40// overflows for const expressions.
41#if defined(OS_WIN)
42#pragma warning(disable:4756)
43#endif
44
jschuhfafe0712015-09-14 20:21:2445// This is a helper function for finding the maximum value in Src that can be
46// wholy represented as the destination floating-point type.
47template <typename Dst, typename Src>
48Dst GetMaxConvertibleToFloat() {
49 typedef numeric_limits<Dst> DstLimits;
50 typedef numeric_limits<Src> SrcLimits;
51 static_assert(SrcLimits::is_specialized, "Source must be numeric.");
52 static_assert(DstLimits::is_specialized, "Destination must be numeric.");
53 CHECK(DstLimits::is_iec559);
54
55 if (SrcLimits::digits <= DstLimits::digits &&
56 MaxExponent<Src>::value <= MaxExponent<Dst>::value)
57 return SrcLimits::max();
58 Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
59 while (max != static_cast<Src>(static_cast<Dst>(max))) {
60 max /= 2;
61 }
62 return static_cast<Dst>(max);
63}
64
[email protected]5bfecbc2014-02-27 13:49:0465// Helper macros to wrap displaying the conversion types and line numbers.
66#define TEST_EXPECTED_VALIDITY(expected, actual) \
jschuh819c8262016-05-21 01:39:0367 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \
[email protected]5bfecbc2014-02-27 13:49:0468 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \
69 << " on line " << line;
70
jschuh819c8262016-05-21 01:39:0371#define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
72#define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
73
[email protected]5bfecbc2014-02-27 13:49:0474#define TEST_EXPECTED_VALUE(expected, actual) \
75 EXPECT_EQ(static_cast<Dst>(expected), \
76 CheckedNumeric<Dst>(actual).ValueUnsafe()) \
77 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \
78 << " on line " << line;
79
80// Signed integer arithmetic.
81template <typename Dst>
82static void TestSpecializedArithmetic(
83 const char* dst,
84 int line,
vmpstr98a2fad2015-11-30 20:15:1785 typename std::enable_if<numeric_limits<Dst>::is_integer &&
86 numeric_limits<Dst>::is_signed,
87 int>::type = 0) {
[email protected]5bfecbc2014-02-27 13:49:0488 typedef numeric_limits<Dst> DstLimits;
jschuh819c8262016-05-21 01:39:0389 TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::min()));
90 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()).Abs());
[email protected]5bfecbc2014-02-27 13:49:0491 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
92
jschuh819c8262016-05-21 01:39:0393 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
94 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1);
95 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) +
96 -DstLimits::max());
[email protected]5bfecbc2014-02-27 13:49:0497
jschuh819c8262016-05-21 01:39:0398 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1);
99 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) - -1);
100 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
101 -DstLimits::max());
102 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) -
103 DstLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04104
jschuh819c8262016-05-21 01:39:03105 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * 2);
[email protected]5bfecbc2014-02-27 13:49:04106
jschuh819c8262016-05-21 01:39:03107 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) / -1);
[email protected]5bfecbc2014-02-27 13:49:04108 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
109
110 // Modulus is legal only for integers.
111 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
112 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
113 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
jschuh819c8262016-05-21 01:39:03114 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2);
[email protected]5bfecbc2014-02-27 13:49:04115 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
116 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
117 // Test all the different modulus combinations.
118 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
119 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
120 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
121 CheckedNumeric<Dst> checked_dst = 1;
122 TEST_EXPECTED_VALUE(0, checked_dst %= 1);
123}
124
125// Unsigned integer arithmetic.
126template <typename Dst>
127static void TestSpecializedArithmetic(
128 const char* dst,
129 int line,
vmpstr98a2fad2015-11-30 20:15:17130 typename std::enable_if<numeric_limits<Dst>::is_integer &&
131 !numeric_limits<Dst>::is_signed,
132 int>::type = 0) {
[email protected]5bfecbc2014-02-27 13:49:04133 typedef numeric_limits<Dst> DstLimits;
jschuh819c8262016-05-21 01:39:03134 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min()));
135 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs());
136 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1);
137 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1);
[email protected]5bfecbc2014-02-27 13:49:04138 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2);
139 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
jschuh819c8262016-05-21 01:39:03140 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs());
141 TEST_EXPECTED_SUCCESS(
jschuheaf375f2015-09-17 01:04:28142 CheckedNumeric<typename SignedIntegerForSize<Dst>::type>(
143 std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min())
144 .UnsignedAbs());
[email protected]5bfecbc2014-02-27 13:49:04145
146 // Modulus is legal only for integers.
147 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
148 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
149 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
150 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
151 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
152 // Test all the different modulus combinations.
153 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
154 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
155 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
156 CheckedNumeric<Dst> checked_dst = 1;
157 TEST_EXPECTED_VALUE(0, checked_dst %= 1);
158}
159
160// Floating point arithmetic.
161template <typename Dst>
162void TestSpecializedArithmetic(
163 const char* dst,
164 int line,
vmpstr98a2fad2015-11-30 20:15:17165 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
[email protected]5bfecbc2014-02-27 13:49:04166 typedef numeric_limits<Dst> DstLimits;
jschuh819c8262016-05-21 01:39:03167 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min()));
[email protected]5bfecbc2014-02-27 13:49:04168
jschuh819c8262016-05-21 01:39:03169 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs());
[email protected]5bfecbc2014-02-27 13:49:04170 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
171
jschuh819c8262016-05-21 01:39:03172 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + -1);
173 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
174 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) +
175 -DstLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04176
jschuh819c8262016-05-21 01:39:03177 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
178 -DstLimits::max());
179 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) -
180 DstLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04181
jschuh819c8262016-05-21 01:39:03182 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) * 2);
[email protected]5bfecbc2014-02-27 13:49:04183
184 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
185 EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating());
186}
187
188// Generic arithmetic tests.
189template <typename Dst>
190static void TestArithmetic(const char* dst, int line) {
191 typedef numeric_limits<Dst> DstLimits;
192
193 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
194 EXPECT_EQ(false,
195 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
196 DstLimits::max()).IsValid());
197 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
198 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
199 EXPECT_EQ(static_cast<Dst>(1),
200 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
201 DstLimits::max()).ValueOrDefault(1));
202
203 // Test the operator combinations.
204 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
205 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
206 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
207 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
208 TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
209 TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
210 TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
211 TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
212 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
213 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
214 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
215 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
216 CheckedNumeric<Dst> checked_dst = 1;
217 TEST_EXPECTED_VALUE(2, checked_dst += 1);
218 checked_dst = 1;
219 TEST_EXPECTED_VALUE(0, checked_dst -= 1);
220 checked_dst = 1;
221 TEST_EXPECTED_VALUE(1, checked_dst *= 1);
222 checked_dst = 1;
223 TEST_EXPECTED_VALUE(1, checked_dst /= 1);
224
225 // Generic negation.
jschuh749c7f72016-09-07 16:22:26226 if (DstLimits::is_signed) {
227 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
228 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
229 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
230 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
231 -CheckedNumeric<Dst>(DstLimits::max()));
232 }
[email protected]5bfecbc2014-02-27 13:49:04233
234 // Generic absolute value.
235 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
236 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
237 TEST_EXPECTED_VALUE(DstLimits::max(),
238 CheckedNumeric<Dst>(DstLimits::max()).Abs());
239
240 // Generic addition.
241 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
242 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
243 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
jschuh819c8262016-05-21 01:39:03244 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + 1);
245 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) +
246 DstLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04247
248 // Generic subtraction.
249 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
250 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
251 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
jschuh819c8262016-05-21 01:39:03252 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
[email protected]5bfecbc2014-02-27 13:49:04253
254 // Generic multiplication.
255 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
256 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
eroman0397125f2015-05-18 14:44:32257 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
258 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
259 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
jschuh819c8262016-05-21 01:39:03260 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
261 DstLimits::max());
jschuh749c7f72016-09-07 16:22:26262 if (DstLimits::is_signed) {
263 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
264 }
[email protected]5bfecbc2014-02-27 13:49:04265
266 // Generic division.
267 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
268 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
269 TEST_EXPECTED_VALUE(DstLimits::min() / 2,
270 CheckedNumeric<Dst>(DstLimits::min()) / 2);
271 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
272 CheckedNumeric<Dst>(DstLimits::max()) / 2);
273
274 TestSpecializedArithmetic<Dst>(dst, line);
275}
276
277// Helper macro to wrap displaying the conversion types and line numbers.
278#define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
279
280TEST(SafeNumerics, SignedIntegerMath) {
281 TEST_ARITHMETIC(int8_t);
282 TEST_ARITHMETIC(int);
283 TEST_ARITHMETIC(intptr_t);
284 TEST_ARITHMETIC(intmax_t);
285}
286
287TEST(SafeNumerics, UnsignedIntegerMath) {
288 TEST_ARITHMETIC(uint8_t);
289 TEST_ARITHMETIC(unsigned int);
290 TEST_ARITHMETIC(uintptr_t);
291 TEST_ARITHMETIC(uintmax_t);
292}
293
294TEST(SafeNumerics, FloatingPointMath) {
295 TEST_ARITHMETIC(float);
296 TEST_ARITHMETIC(double);
297}
[email protected]c1c090d32013-01-16 23:34:04298
[email protected]4efb2c32014-01-16 06:57:25299// Enumerates the five different conversions types we need to test.
300enum NumericConversionType {
301 SIGN_PRESERVING_VALUE_PRESERVING,
302 SIGN_PRESERVING_NARROW,
303 SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
304 SIGN_TO_UNSIGN_NARROW,
305 UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
306};
[email protected]c1c090d32013-01-16 23:34:04307
[email protected]4efb2c32014-01-16 06:57:25308// Template covering the different conversion tests.
309template <typename Dst, typename Src, NumericConversionType conversion>
310struct TestNumericConversion {};
[email protected]c1c090d32013-01-16 23:34:04311
[email protected]5bfecbc2014-02-27 13:49:04312// EXPECT_EQ wrappers providing specific detail on test failures.
313#define TEST_EXPECTED_RANGE(expected, actual) \
314 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \
315 << "Conversion test: " << src << " value " << actual << " to " << dst \
316 << " on line " << line;
[email protected]4efb2c32014-01-16 06:57:25317
318template <typename Dst, typename Src>
319struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
320 static void Test(const char *dst, const char *src, int line) {
[email protected]5bfecbc2014-02-27 13:49:04321 typedef numeric_limits<Src> SrcLimits;
322 typedef numeric_limits<Dst> DstLimits;
[email protected]4efb2c32014-01-16 06:57:25323 // Integral to floating.
jschuhd2d9fe02014-10-14 14:31:37324 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
325 // Not floating to integral and...
326 (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
327 // Same sign, same numeric, source is narrower or same.
328 ((SrcLimits::is_signed == DstLimits::is_signed &&
329 sizeof(Dst) >= sizeof(Src)) ||
330 // Or signed destination and source is smaller
331 (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))),
332 "Comparison must be sign preserving and value preserving");
[email protected]4efb2c32014-01-16 06:57:25333
[email protected]5bfecbc2014-02-27 13:49:04334 const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
jschuh819c8262016-05-21 01:39:03335 TEST_EXPECTED_SUCCESS(checked_dst);
[email protected]5bfecbc2014-02-27 13:49:04336 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
337 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
338 // At least twice larger type.
jschuh819c8262016-05-21 01:39:03339 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
[email protected]5bfecbc2014-02-27 13:49:04340
341 } else { // Larger, but not at least twice as large.
jschuh819c8262016-05-21 01:39:03342 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
343 TEST_EXPECTED_SUCCESS(checked_dst + 1);
[email protected]5bfecbc2014-02-27 13:49:04344 }
345 } else { // Same width type.
jschuh819c8262016-05-21 01:39:03346 TEST_EXPECTED_FAILURE(checked_dst + 1);
[email protected]5bfecbc2014-02-27 13:49:04347 }
348
349 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
350 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
[email protected]4efb2c32014-01-16 06:57:25351 if (SrcLimits::is_iec559) {
[email protected]5bfecbc2014-02-27 13:49:04352 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
353 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
354 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
355 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
[email protected]5bfecbc2014-02-27 13:49:04356 } else if (numeric_limits<Src>::is_signed) {
357 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
358 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
[email protected]4efb2c32014-01-16 06:57:25359 }
[email protected]c1c090d32013-01-16 23:34:04360 }
[email protected]4efb2c32014-01-16 06:57:25361};
362
363template <typename Dst, typename Src>
364struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
365 static void Test(const char *dst, const char *src, int line) {
[email protected]5bfecbc2014-02-27 13:49:04366 typedef numeric_limits<Src> SrcLimits;
367 typedef numeric_limits<Dst> DstLimits;
jschuhd2d9fe02014-10-14 14:31:37368 static_assert(SrcLimits::is_signed == DstLimits::is_signed,
369 "Destination and source sign must be the same");
370 static_assert(sizeof(Dst) < sizeof(Src) ||
[email protected]4efb2c32014-01-16 06:57:25371 (DstLimits::is_integer && SrcLimits::is_iec559),
jschuhd2d9fe02014-10-14 14:31:37372 "Destination must be narrower than source");
[email protected]4efb2c32014-01-16 06:57:25373
[email protected]5bfecbc2014-02-27 13:49:04374 const CheckedNumeric<Dst> checked_dst;
jschuh819c8262016-05-21 01:39:03375 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04376 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
jschuh819c8262016-05-21 01:39:03377 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04378
379 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
380 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
[email protected]4efb2c32014-01-16 06:57:25381 if (SrcLimits::is_iec559) {
[email protected]5bfecbc2014-02-27 13:49:04382 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
383 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
384 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
385 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
386 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
jschuhfafe0712015-09-14 20:21:24387 if (DstLimits::is_integer) {
388 if (SrcLimits::digits < DstLimits::digits) {
389 TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
390 static_cast<Src>(DstLimits::max()));
391 } else {
392 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
393 }
394 TEST_EXPECTED_RANGE(
395 RANGE_VALID,
396 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
397 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
398 }
[email protected]4efb2c32014-01-16 06:57:25399 } else if (SrcLimits::is_signed) {
[email protected]5bfecbc2014-02-27 13:49:04400 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
401 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
402 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
[email protected]4efb2c32014-01-16 06:57:25403 } else {
jschuh819c8262016-05-21 01:39:03404 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
[email protected]5bfecbc2014-02-27 13:49:04405 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
[email protected]4efb2c32014-01-16 06:57:25406 }
407 }
408};
409
410template <typename Dst, typename Src>
411struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
412 static void Test(const char *dst, const char *src, int line) {
[email protected]5bfecbc2014-02-27 13:49:04413 typedef numeric_limits<Src> SrcLimits;
414 typedef numeric_limits<Dst> DstLimits;
jschuhd2d9fe02014-10-14 14:31:37415 static_assert(sizeof(Dst) >= sizeof(Src),
416 "Destination must be equal or wider than source.");
417 static_assert(SrcLimits::is_signed, "Source must be signed");
418 static_assert(!DstLimits::is_signed, "Destination must be unsigned");
[email protected]4efb2c32014-01-16 06:57:25419
[email protected]5bfecbc2014-02-27 13:49:04420 const CheckedNumeric<Dst> checked_dst;
421 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
jschuh819c8262016-05-21 01:39:03422 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
423 TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04424
425 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
426 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
427 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
428 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
[email protected]4efb2c32014-01-16 06:57:25429 }
430};
431
432template <typename Dst, typename Src>
433struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
434 static void Test(const char *dst, const char *src, int line) {
[email protected]5bfecbc2014-02-27 13:49:04435 typedef numeric_limits<Src> SrcLimits;
436 typedef numeric_limits<Dst> DstLimits;
jschuhd2d9fe02014-10-14 14:31:37437 static_assert((DstLimits::is_integer && SrcLimits::is_iec559) ||
[email protected]4efb2c32014-01-16 06:57:25438 (sizeof(Dst) < sizeof(Src)),
jschuhd2d9fe02014-10-14 14:31:37439 "Destination must be narrower than source.");
440 static_assert(SrcLimits::is_signed, "Source must be signed.");
441 static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
[email protected]4efb2c32014-01-16 06:57:25442
[email protected]5bfecbc2014-02-27 13:49:04443 const CheckedNumeric<Dst> checked_dst;
444 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
jschuh819c8262016-05-21 01:39:03445 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
446 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
447 TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04448
449 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
450 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
451 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
[email protected]4efb2c32014-01-16 06:57:25452 if (SrcLimits::is_iec559) {
[email protected]5bfecbc2014-02-27 13:49:04453 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
454 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
455 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
456 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
jschuhfafe0712015-09-14 20:21:24457 if (DstLimits::is_integer) {
458 if (SrcLimits::digits < DstLimits::digits) {
459 TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
460 static_cast<Src>(DstLimits::max()));
461 } else {
462 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
463 }
464 TEST_EXPECTED_RANGE(
465 RANGE_VALID,
466 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
467 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
468 }
[email protected]4efb2c32014-01-16 06:57:25469 } else {
[email protected]5bfecbc2014-02-27 13:49:04470 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
[email protected]4efb2c32014-01-16 06:57:25471 }
472 }
473};
474
475template <typename Dst, typename Src>
476struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
477 static void Test(const char *dst, const char *src, int line) {
[email protected]5bfecbc2014-02-27 13:49:04478 typedef numeric_limits<Src> SrcLimits;
479 typedef numeric_limits<Dst> DstLimits;
jschuhd2d9fe02014-10-14 14:31:37480 static_assert(sizeof(Dst) <= sizeof(Src),
481 "Destination must be narrower or equal to source.");
482 static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
483 static_assert(DstLimits::is_signed, "Destination must be signed.");
[email protected]4efb2c32014-01-16 06:57:25484
[email protected]5bfecbc2014-02-27 13:49:04485 const CheckedNumeric<Dst> checked_dst;
486 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
jschuh819c8262016-05-21 01:39:03487 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
[email protected]5bfecbc2014-02-27 13:49:04488 TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min());
489
490 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
491 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
492 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
[email protected]4efb2c32014-01-16 06:57:25493 }
494};
495
496// Helper macro to wrap displaying the conversion types and line numbers
497#define TEST_NUMERIC_CONVERSION(d, s, t) \
498 TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
499
[email protected]5bfecbc2014-02-27 13:49:04500TEST(SafeNumerics, IntMinOperations) {
[email protected]4efb2c32014-01-16 06:57:25501 TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
502 TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
503
504 TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
505 TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
506 TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
507
508 TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
509
510 TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
511 TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
512 TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
513
514 TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
515 TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
[email protected]c1c090d32013-01-16 23:34:04516}
517
[email protected]5bfecbc2014-02-27 13:49:04518TEST(SafeNumerics, IntOperations) {
[email protected]4efb2c32014-01-16 06:57:25519 TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
520 TEST_NUMERIC_CONVERSION(unsigned int, unsigned int,
521 SIGN_PRESERVING_VALUE_PRESERVING);
522 TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
523 TEST_NUMERIC_CONVERSION(unsigned int, uint8_t,
524 SIGN_PRESERVING_VALUE_PRESERVING);
525 TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
526
527 TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
528 TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
529 TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
530 TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
531
532 TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
533 TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
534
535 TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
536 TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
537 TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
538
539 TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
540 TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
[email protected]c1c090d32013-01-16 23:34:04541}
542
[email protected]5bfecbc2014-02-27 13:49:04543TEST(SafeNumerics, IntMaxOperations) {
[email protected]4efb2c32014-01-16 06:57:25544 TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
545 TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t,
546 SIGN_PRESERVING_VALUE_PRESERVING);
547 TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
548 TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int,
549 SIGN_PRESERVING_VALUE_PRESERVING);
550 TEST_NUMERIC_CONVERSION(intmax_t, unsigned int,
551 SIGN_PRESERVING_VALUE_PRESERVING);
552 TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
553
554 TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
555 TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
556
557 TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
558 TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
559
560 TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
561 TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
562
563 TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
564}
565
[email protected]5bfecbc2014-02-27 13:49:04566TEST(SafeNumerics, FloatOperations) {
[email protected]4efb2c32014-01-16 06:57:25567 TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
568 TEST_NUMERIC_CONVERSION(float, uintmax_t,
569 SIGN_PRESERVING_VALUE_PRESERVING);
570 TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
571 TEST_NUMERIC_CONVERSION(float, unsigned int,
572 SIGN_PRESERVING_VALUE_PRESERVING);
573
574 TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
575}
576
[email protected]5bfecbc2014-02-27 13:49:04577TEST(SafeNumerics, DoubleOperations) {
[email protected]4efb2c32014-01-16 06:57:25578 TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
579 TEST_NUMERIC_CONVERSION(double, uintmax_t,
580 SIGN_PRESERVING_VALUE_PRESERVING);
581 TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
582 TEST_NUMERIC_CONVERSION(double, unsigned int,
583 SIGN_PRESERVING_VALUE_PRESERVING);
584}
585
[email protected]5bfecbc2014-02-27 13:49:04586TEST(SafeNumerics, SizeTOperations) {
[email protected]4efb2c32014-01-16 06:57:25587 TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
588 TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
589}
590
591TEST(SafeNumerics, CastTests) {
592// MSVC catches and warns that we're forcing saturation in these tests.
593// Since that's intentional, we need to shut this warning off.
594#if defined(COMPILER_MSVC)
595#pragma warning(disable : 4756)
[email protected]c1c090d32013-01-16 23:34:04596#endif
597
[email protected]c1c090d32013-01-16 23:34:04598 int small_positive = 1;
599 int small_negative = -1;
[email protected]4efb2c32014-01-16 06:57:25600 double double_small = 1.0;
[email protected]5bfecbc2014-02-27 13:49:04601 double double_large = numeric_limits<double>::max();
602 double double_infinity = numeric_limits<float>::infinity();
danakj3193742f2015-06-05 18:15:10603 double double_large_int = numeric_limits<int>::max();
604 double double_small_int = numeric_limits<int>::min();
[email protected]c1c090d32013-01-16 23:34:04605
jschuh4bf22c6d2015-05-28 02:29:25606 // Just test that the casts compile, since the other tests cover logic.
[email protected]5bfecbc2014-02-27 13:49:04607 EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
jschuh4bf22c6d2015-05-28 02:29:25608 EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
609 EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
610 EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
611 EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
612 EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
613 EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
614
615 EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
616 EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
617 EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
618
jschuh07345e62015-09-22 22:13:36619 EXPECT_TRUE(IsValueNegative(-1));
620 EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min()));
621 EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min()));
622 EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max()));
623 EXPECT_FALSE(IsValueNegative(0));
624 EXPECT_FALSE(IsValueNegative(1));
625 EXPECT_FALSE(IsValueNegative(0u));
626 EXPECT_FALSE(IsValueNegative(1u));
627 EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
628 EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
629 EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
630
jschuh4bf22c6d2015-05-28 02:29:25631 // These casts and coercions will fail to compile:
632 // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
633 // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
634 // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
635 // EXPECT_EQ(1, StrictNumeric<size_t>(1U));
[email protected]c1c090d32013-01-16 23:34:04636
[email protected]4efb2c32014-01-16 06:57:25637 // Test various saturation corner cases.
638 EXPECT_EQ(saturated_cast<int>(small_negative),
639 static_cast<int>(small_negative));
640 EXPECT_EQ(saturated_cast<int>(small_positive),
641 static_cast<int>(small_positive));
642 EXPECT_EQ(saturated_cast<unsigned>(small_negative),
643 static_cast<unsigned>(0));
644 EXPECT_EQ(saturated_cast<int>(double_small),
645 static_cast<int>(double_small));
[email protected]5bfecbc2014-02-27 13:49:04646 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
[email protected]4efb2c32014-01-16 06:57:25647 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
648 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
danakj3193742f2015-06-05 18:15:10649 EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int));
650 EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
vmpstredf1e182015-12-14 20:09:42651
652 float not_a_number = std::numeric_limits<float>::infinity() -
653 std::numeric_limits<float>::infinity();
654 EXPECT_TRUE(std::isnan(not_a_number));
655 EXPECT_EQ(0, saturated_cast<int>(not_a_number));
[email protected]c1c090d32013-01-16 23:34:04656}
657
vmpstredf1e182015-12-14 20:09:42658TEST(SafeNumerics, SaturatedCastChecks) {
659 float not_a_number = std::numeric_limits<float>::infinity() -
660 std::numeric_limits<float>::infinity();
661 EXPECT_TRUE(std::isnan(not_a_number));
xyzzyz0015f582016-08-15 20:50:02662 EXPECT_DEATH_IF_SUPPORTED(
663 (saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>(not_a_number)),
664 "");
vmpstredf1e182015-12-14 20:09:42665}
666
jschuhfafe0712015-09-14 20:21:24667TEST(SafeNumerics, IsValueInRangeForNumericType) {
668 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
669 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
670 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
671 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
672 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
673 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
674 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
675 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
676 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
677 std::numeric_limits<int32_t>::min()));
678 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
679 std::numeric_limits<int64_t>::min()));
680
681 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
682 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
683 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
684 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
685 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
686 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
687 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
688 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
689 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
690 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
691 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
692 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
693 std::numeric_limits<int32_t>::min()));
694 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
danakja5f0d962015-09-15 20:27:24695 static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
jschuhfafe0712015-09-14 20:21:24696 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
danakja5f0d962015-09-15 20:27:24697 static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1));
jschuhfafe0712015-09-14 20:21:24698 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
699 std::numeric_limits<int64_t>::min()));
700
701 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
702 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
703 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
704 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
705 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
706 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
707 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
708 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
709 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
710 std::numeric_limits<int32_t>::min()));
711 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
712 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
713 std::numeric_limits<int64_t>::min()));
714
715 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
716 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
717 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
718 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
719 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
720 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
721 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
722 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
723 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
724 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
725 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
726 EXPECT_TRUE(
727 IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
728 EXPECT_TRUE(
729 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
730 EXPECT_FALSE(
731 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
732 EXPECT_FALSE(
733 IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
734 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
735 std::numeric_limits<int32_t>::min()));
736 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
danakja5f0d962015-09-15 20:27:24737 static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
jschuhfafe0712015-09-14 20:21:24738 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
739 std::numeric_limits<int64_t>::min()));
740}
vmpstr19477492015-09-29 22:34:49741
742TEST(SafeNumerics, CompoundNumericOperations) {
743 CheckedNumeric<int> a = 1;
744 CheckedNumeric<int> b = 2;
745 CheckedNumeric<int> c = 3;
746 CheckedNumeric<int> d = 4;
747 a += b;
748 EXPECT_EQ(3, a.ValueOrDie());
749 a -= c;
750 EXPECT_EQ(0, a.ValueOrDie());
751 d /= b;
752 EXPECT_EQ(2, d.ValueOrDie());
753 d *= d;
754 EXPECT_EQ(4, d.ValueOrDie());
755
756 CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
757 EXPECT_TRUE(too_large.IsValid());
758 too_large += d;
759 EXPECT_FALSE(too_large.IsValid());
760 too_large -= d;
761 EXPECT_FALSE(too_large.IsValid());
762 too_large /= d;
763 EXPECT_FALSE(too_large.IsValid());
764}