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::saturated_cast; | 21 using base::saturated_cast; |
22 using base::internal::MaxExponent; | 22 using base::internal::MaxExponent; |
23 using base::internal::RANGE_VALID; | 23 using base::internal::RANGE_VALID; |
24 using base::internal::RANGE_INVALID; | 24 using base::internal::RANGE_INVALID; |
25 using base::internal::RANGE_OVERFLOW; | 25 using base::internal::RANGE_OVERFLOW; |
26 using base::internal::RANGE_UNDERFLOW; | 26 using base::internal::RANGE_UNDERFLOW; |
27 using base::enable_if; | 27 using base::enable_if; |
28 | 28 |
29 // MSVS 2013 ia32 may not reset the FPU between calculations, and the test | |
30 // framework masks the exceptions. So we just force a manual reset after NaN. | |
31 inline void ResetFloatingPointUnit() { | |
32 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) | |
33 _mm_empty(); | |
34 #endif | |
35 } | |
36 | |
37 // These tests deliberately cause arithmetic overflows. If the compiler is | 29 // These tests deliberately cause arithmetic overflows. If the compiler is |
38 // aggressive enough, it can const fold these overflows. Disable warnings about | 30 // aggressive enough, it can const fold these overflows. Disable warnings about |
39 // overflows for const expressions. | 31 // overflows for const expressions. |
40 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
41 #pragma warning(disable:4756) | 33 #pragma warning(disable:4756) |
42 #endif | 34 #endif |
43 | 35 |
44 // Helper macros to wrap displaying the conversion types and line numbers. | 36 // Helper macros to wrap displaying the conversion types and line numbers. |
45 #define TEST_EXPECTED_VALIDITY(expected, actual) \ | 37 #define TEST_EXPECTED_VALIDITY(expected, actual) \ |
46 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \ | 38 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \ |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + 1); | 326 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + 1); |
335 } | 327 } |
336 | 328 |
337 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); | 329 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); |
338 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 330 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
339 if (SrcLimits::is_iec559) { | 331 if (SrcLimits::is_iec559) { |
340 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); | 332 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); |
341 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 333 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
342 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 334 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
343 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 335 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
344 ResetFloatingPointUnit(); | |
345 } else if (numeric_limits<Src>::is_signed) { | 336 } else if (numeric_limits<Src>::is_signed) { |
346 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 337 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
347 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 338 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
348 } | 339 } |
349 } | 340 } |
350 }; | 341 }; |
351 | 342 |
352 template <typename Dst, typename Src> | 343 template <typename Dst, typename Src> |
353 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { | 344 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { |
354 static void Test(const char *dst, const char *src, int line) { | 345 static void Test(const char *dst, const char *src, int line) { |
(...skipping 11 matching lines...) Expand all Loading... |
366 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); | 357 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); |
367 | 358 |
368 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 359 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
369 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 360 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
370 if (SrcLimits::is_iec559) { | 361 if (SrcLimits::is_iec559) { |
371 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 362 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
372 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 363 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
373 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 364 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
374 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 365 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
375 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 366 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
376 ResetFloatingPointUnit(); | |
377 } else if (SrcLimits::is_signed) { | 367 } else if (SrcLimits::is_signed) { |
378 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); | 368 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); |
379 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 369 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
380 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 370 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
381 } else { | 371 } else { |
382 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); | 372 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); |
383 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 373 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
384 } | 374 } |
385 } | 375 } |
386 }; | 376 }; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); | 415 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); |
426 | 416 |
427 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 417 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
428 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 418 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
429 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); | 419 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); |
430 if (SrcLimits::is_iec559) { | 420 if (SrcLimits::is_iec559) { |
431 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 421 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
432 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 422 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
433 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 423 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
434 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 424 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
435 ResetFloatingPointUnit(); | |
436 } else { | 425 } else { |
437 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 426 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
438 } | 427 } |
439 } | 428 } |
440 }; | 429 }; |
441 | 430 |
442 template <typename Dst, typename Src> | 431 template <typename Dst, typename Src> |
443 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { | 432 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { |
444 static void Test(const char *dst, const char *src, int line) { | 433 static void Test(const char *dst, const char *src, int line) { |
445 typedef numeric_limits<Src> SrcLimits; | 434 typedef numeric_limits<Src> SrcLimits; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 static_cast<int>(small_positive)); | 567 static_cast<int>(small_positive)); |
579 EXPECT_EQ(saturated_cast<unsigned>(small_negative), | 568 EXPECT_EQ(saturated_cast<unsigned>(small_negative), |
580 static_cast<unsigned>(0)); | 569 static_cast<unsigned>(0)); |
581 EXPECT_EQ(saturated_cast<int>(double_small), | 570 EXPECT_EQ(saturated_cast<int>(double_small), |
582 static_cast<int>(double_small)); | 571 static_cast<int>(double_small)); |
583 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); | 572 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); |
584 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); | 573 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); |
585 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); | 574 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); |
586 } | 575 } |
587 | 576 |
OLD | NEW |