| 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 | 
|---|