| 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/logging.h" | 12 #include "base/logging.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/test/gtest_util.h" | 15 #include "base/test/gtest_util.h" |
| 16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) | 19 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) |
| 20 #include <mmintrin.h> | 20 #include <mmintrin.h> |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 using std::numeric_limits; | 23 using std::numeric_limits; |
| 24 using base::CheckedNumeric; | 24 using base::CheckedNumeric; |
| 25 using base::IsValidForType; | 25 using base::IsValidForType; |
| 26 using base::ValueOrDieForType; | 26 using base::ValueOrDieForType; |
| 27 using base::ValueOrDefaultForType; | 27 using base::ValueOrDefaultForType; |
| 28 using base::CheckNum; | 28 using base::CheckNum; |
| 29 using base::CheckMax; |
| 30 using base::CheckMin; |
| 29 using base::CheckAdd; | 31 using base::CheckAdd; |
| 30 using base::CheckSub; | 32 using base::CheckSub; |
| 31 using base::CheckMul; | 33 using base::CheckMul; |
| 32 using base::CheckDiv; | 34 using base::CheckDiv; |
| 33 using base::CheckMod; | 35 using base::CheckMod; |
| 34 using base::CheckLsh; | 36 using base::CheckLsh; |
| 35 using base::CheckRsh; | 37 using base::CheckRsh; |
| 36 using base::checked_cast; | 38 using base::checked_cast; |
| 37 using base::IsValueInRangeForNumericType; | 39 using base::IsValueInRangeForNumericType; |
| 38 using base::IsValueNegative; | 40 using base::IsValueNegative; |
| 39 using base::SizeT; | 41 using base::SizeT; |
| 40 using base::StrictNumeric; | 42 using base::StrictNumeric; |
| 43 using base::MakeStrictNum; |
| 41 using base::saturated_cast; | 44 using base::saturated_cast; |
| 42 using base::strict_cast; | 45 using base::strict_cast; |
| 43 using base::StrictNumeric; | |
| 44 using base::internal::MaxExponent; | 46 using base::internal::MaxExponent; |
| 45 using base::internal::RANGE_VALID; | 47 using base::internal::RANGE_VALID; |
| 46 using base::internal::RANGE_INVALID; | 48 using base::internal::RANGE_INVALID; |
| 47 using base::internal::RANGE_OVERFLOW; | 49 using base::internal::RANGE_OVERFLOW; |
| 48 using base::internal::RANGE_UNDERFLOW; | 50 using base::internal::RANGE_UNDERFLOW; |
| 49 using base::internal::SignedIntegerForSize; | 51 using base::internal::SignedIntegerForSize; |
| 50 | 52 |
| 51 // These tests deliberately cause arithmetic boundary errors. If the compiler is | 53 // These tests deliberately cause arithmetic boundary errors. If the compiler is |
| 52 // aggressive enough, it can const detect these errors, so we disable warnings. | 54 // aggressive enough, it can const detect these errors, so we disable warnings. |
| 53 #if defined(OS_WIN) | 55 #if defined(OS_WIN) |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 // EXPECT_EQ wrappers providing specific detail on test failures. | 433 // EXPECT_EQ wrappers providing specific detail on test failures. |
| 432 #define TEST_EXPECTED_RANGE(expected, actual) \ | 434 #define TEST_EXPECTED_RANGE(expected, actual) \ |
| 433 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ | 435 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ |
| 434 << "Conversion test: " << src << " value " << actual << " to " << dst \ | 436 << "Conversion test: " << src << " value " << actual << " to " << dst \ |
| 435 << " on line " << line | 437 << " on line " << line |
| 436 | 438 |
| 437 template <typename Dst, typename Src> | 439 template <typename Dst, typename Src> |
| 438 void TestStrictComparison() { | 440 void TestStrictComparison() { |
| 439 typedef numeric_limits<Dst> DstLimits; | 441 typedef numeric_limits<Dst> DstLimits; |
| 440 typedef numeric_limits<Src> SrcLimits; | 442 typedef numeric_limits<Src> SrcLimits; |
| 441 static_assert(StrictNumeric<Src>(SrcLimits::min()) < DstLimits::max(), ""); | 443 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), ""); |
| 442 static_assert(StrictNumeric<Src>(SrcLimits::min()) < SrcLimits::max(), ""); | 444 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), ""); |
| 443 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) >= DstLimits::max()), | 445 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()), |
| 444 ""); | 446 ""); |
| 445 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) >= SrcLimits::max()), | 447 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= SrcLimits::max()), |
| 446 ""); | 448 ""); |
| 447 static_assert(StrictNumeric<Src>(SrcLimits::min()) <= DstLimits::max(), ""); | 449 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= DstLimits::max(), |
| 448 static_assert(StrictNumeric<Src>(SrcLimits::min()) <= SrcLimits::max(), ""); | |
| 449 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) > DstLimits::max()), ""); | |
| 450 static_assert(!(StrictNumeric<Src>(SrcLimits::min()) > SrcLimits::max()), ""); | |
| 451 static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::min(), ""); | |
| 452 static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::min(), ""); | |
| 453 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::min()), | |
| 454 ""); | 450 ""); |
| 455 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::min()), | 451 static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= SrcLimits::max(), |
| 456 ""); | 452 ""); |
| 457 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::min(), ""); | 453 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > DstLimits::max()), |
| 458 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::min(), ""); | 454 ""); |
| 459 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::min()), ""); | 455 static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > SrcLimits::max()), |
| 460 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::min()), ""); | 456 ""); |
| 457 static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::lowest(), ""); |
| 458 static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::lowest(), ""); |
| 459 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::lowest()), |
| 460 ""); |
| 461 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::lowest()), |
| 462 ""); |
| 463 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::lowest(), |
| 464 ""); |
| 465 static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::lowest(), |
| 466 ""); |
| 467 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::lowest()), |
| 468 ""); |
| 469 static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::lowest()), |
| 470 ""); |
| 461 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1), | 471 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1), |
| 462 ""); | 472 ""); |
| 463 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0), | 473 static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0), |
| 464 ""); | 474 ""); |
| 465 static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0), | 475 static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0), |
| 466 ""); | 476 ""); |
| 467 static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::min(), ""); | 477 static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::lowest(), |
| 478 ""); |
| 468 static_assert( | 479 static_assert( |
| 469 !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), ""); | 480 !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), ""); |
| 470 static_assert( | 481 static_assert( |
| 471 !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), ""); | 482 !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), ""); |
| 483 |
| 484 // Due to differences in float handling between compilers, these aren't |
| 485 // compile-time constants everywhere. So, we use run-time tests. |
| 486 EXPECT_EQ(SrcLimits::max(), |
| 487 CheckNum(SrcLimits::max()).Max(DstLimits::lowest()).ValueOrDie()); |
| 488 EXPECT_EQ(DstLimits::max(), |
| 489 CheckNum(SrcLimits::lowest()).Max(DstLimits::max()).ValueOrDie()); |
| 490 EXPECT_EQ(DstLimits::lowest(), |
| 491 CheckNum(SrcLimits::max()).Min(DstLimits::lowest()).ValueOrDie()); |
| 492 EXPECT_EQ(SrcLimits::lowest(), |
| 493 CheckNum(SrcLimits::lowest()).Min(DstLimits::max()).ValueOrDie()); |
| 494 EXPECT_EQ(SrcLimits::lowest(), CheckMin(MakeStrictNum(1), CheckNum(0), |
| 495 DstLimits::max(), SrcLimits::lowest()) |
| 496 .ValueOrDie()); |
| 497 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), CheckNum(0), |
| 498 DstLimits::max(), SrcLimits::lowest()) |
| 499 .ValueOrDie()); |
| 472 } | 500 } |
| 473 | 501 |
| 474 template <typename Dst, typename Src> | 502 template <typename Dst, typename Src> |
| 475 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { | 503 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { |
| 476 static void Test(const char *dst, const char *src, int line) { | 504 static void Test(const char *dst, const char *src, int line) { |
| 477 typedef numeric_limits<Src> SrcLimits; | 505 typedef numeric_limits<Src> SrcLimits; |
| 478 typedef numeric_limits<Dst> DstLimits; | 506 typedef numeric_limits<Dst> DstLimits; |
| 479 // Integral to floating. | 507 // Integral to floating. |
| 480 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || | 508 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || |
| 481 // Not floating to integral and... | 509 // Not floating to integral and... |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); | 1025 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); |
| 998 auto e = CheckMod(CheckNum(20), 3).ValueOrDie(); | 1026 auto e = CheckMod(CheckNum(20), 3).ValueOrDie(); |
| 999 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); | 1027 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); |
| 1000 auto f = CheckLsh(1, CheckNum(2)).ValueOrDie(); | 1028 auto f = CheckLsh(1, CheckNum(2)).ValueOrDie(); |
| 1001 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); | 1029 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); |
| 1002 auto g = CheckRsh(4, CheckNum(2)).ValueOrDie(); | 1030 auto g = CheckRsh(4, CheckNum(2)).ValueOrDie(); |
| 1003 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); | 1031 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); |
| 1004 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); | 1032 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); |
| 1005 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); | 1033 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); |
| 1006 } | 1034 } |
| OLD | NEW |