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 3 // found in the LICENSE file. 4 5 #include <stddef.h> 6 #include <stdint.h> 7 8 #include <limits> 9 #include <type_traits> 10 11 #include "base/compiler_specific.h" 12 #include "base/numerics/safe_conversions.h" 13 #include "base/numerics/safe_math.h" 14 #include "build/build_config.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 17 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) 18 #include <mmintrin.h> 19 #endif 20 21 using std::numeric_limits; 22 using base::CheckedNumeric; 23 using base::checked_cast; 24 using base::IsValueInRangeForNumericType; 25 using base::IsValueNegative; 26 using base::SizeT; 27 using base::StrictNumeric; 28 using base::saturated_cast; 29 using base::strict_cast; 30 using base::internal::MaxExponent; 31 using base::internal::RANGE_VALID; 32 using base::internal::RANGE_INVALID; 33 using base::internal::RANGE_OVERFLOW; 34 using base::internal::RANGE_UNDERFLOW; 35 using base::internal::SignedIntegerForSize; 36 37 // These tests deliberately cause arithmetic overflows. If the compiler is 38 // aggressive enough, it can const fold these overflows. Disable warnings about 39 // overflows for const expressions. 40 #if defined(OS_WIN) 41 #pragma warning(disable:4756) 42 #endif 43 44 // This is a helper function for finding the maximum value in Src that can be 45 // wholy represented as the destination floating-point type. 46 template <typename Dst, typename Src> 47 Dst GetMaxConvertibleToFloat() { 48 typedef numeric_limits<Dst> DstLimits; 49 typedef numeric_limits<Src> SrcLimits; 50 static_assert(SrcLimits::is_specialized, "Source must be numeric."); 51 static_assert(DstLimits::is_specialized, "Destination must be numeric."); 52 CHECK(DstLimits::is_iec559); 53 54 if (SrcLimits::digits <= DstLimits::digits && 55 MaxExponent<Src>::value <= MaxExponent<Dst>::value) 56 return SrcLimits::max(); 57 Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0); 58 while (max != static_cast<Src>(static_cast<Dst>(max))) { 59 max /= 2; 60 } 61 return static_cast<Dst>(max); 62 } 63 64 // Helper macros to wrap displaying the conversion types and line numbers. 65 #define TEST_EXPECTED_VALIDITY(expected, actual) \ 66 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \ 67 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ 68 << " on line " << line; 69 70 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) 71 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) 72 73 #define TEST_EXPECTED_VALUE(expected, actual) \ 74 EXPECT_EQ(static_cast<Dst>(expected), \ 75 CheckedNumeric<Dst>(actual).ValueUnsafe()) \ 76 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ 77 << " on line " << line; 78 79 // Signed integer arithmetic. 80 template <typename Dst> 81 static void TestSpecializedArithmetic( 82 const char* dst, 83 int line, 84 typename std::enable_if<numeric_limits<Dst>::is_integer && 85 numeric_limits<Dst>::is_signed, 86 int>::type = 0) { 87 typedef numeric_limits<Dst> DstLimits; 88 TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::min())); 89 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()).Abs()); 90 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 91 92 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1); 93 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1); 94 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) + 95 -DstLimits::max()); 96 97 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1); 98 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) - -1); 99 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - 100 -DstLimits::max()); 101 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - 102 DstLimits::max()); 103 104 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * 2); 105 106 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) / -1); 107 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); 108 109 // Modulus is legal only for integers. 110 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 111 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 112 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); 113 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2); 114 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); 115 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 116 // Test all the different modulus combinations. 117 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 118 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 119 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 120 CheckedNumeric<Dst> checked_dst = 1; 121 TEST_EXPECTED_VALUE(0, checked_dst %= 1); 122 } 123 124 // Unsigned integer arithmetic. 125 template <typename Dst> 126 static void TestSpecializedArithmetic( 127 const char* dst, 128 int line, 129 typename std::enable_if<numeric_limits<Dst>::is_integer && 130 !numeric_limits<Dst>::is_signed, 131 int>::type = 0) { 132 typedef numeric_limits<Dst> DstLimits; 133 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min())); 134 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs()); 135 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1); 136 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1); 137 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2); 138 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2); 139 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs()); 140 TEST_EXPECTED_SUCCESS( 141 CheckedNumeric<typename SignedIntegerForSize<Dst>::type>( 142 std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min()) 143 .UnsignedAbs()); 144 145 // Modulus is legal only for integers. 146 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 147 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 148 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2); 149 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); 150 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 151 // Test all the different modulus combinations. 152 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 153 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 154 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 155 CheckedNumeric<Dst> checked_dst = 1; 156 TEST_EXPECTED_VALUE(0, checked_dst %= 1); 157 } 158 159 // Floating point arithmetic. 160 template <typename Dst> 161 void TestSpecializedArithmetic( 162 const char* dst, 163 int line, 164 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { 165 typedef numeric_limits<Dst> DstLimits; 166 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min())); 167 168 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs()); 169 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 170 171 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + -1); 172 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1); 173 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) + 174 -DstLimits::max()); 175 176 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - 177 -DstLimits::max()); 178 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - 179 DstLimits::max()); 180 181 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) * 2); 182 183 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2); 184 EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating()); 185 } 186 187 // Generic arithmetic tests. 188 template <typename Dst> 189 static void TestArithmetic(const char* dst, int line) { 190 typedef numeric_limits<Dst> DstLimits; 191 192 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid()); 193 EXPECT_EQ(false, 194 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 195 DstLimits::max()).IsValid()); 196 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie()); 197 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1)); 198 EXPECT_EQ(static_cast<Dst>(1), 199 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 200 DstLimits::max()).ValueOrDefault(1)); 201 202 // Test the operator combinations. 203 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1)); 204 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1)); 205 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1)); 206 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1)); 207 TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1)); 208 TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1)); 209 TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1)); 210 TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1)); 211 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1); 212 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1); 213 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1); 214 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 215 CheckedNumeric<Dst> checked_dst = 1; 216 TEST_EXPECTED_VALUE(2, checked_dst += 1); 217 checked_dst = 1; 218 TEST_EXPECTED_VALUE(0, checked_dst -= 1); 219 checked_dst = 1; 220 TEST_EXPECTED_VALUE(1, checked_dst *= 1); 221 checked_dst = 1; 222 TEST_EXPECTED_VALUE(1, checked_dst /= 1); 223 224 // Generic negation. 225 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>()); 226 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1)); 227 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1)); 228 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1), 229 -CheckedNumeric<Dst>(DstLimits::max())); 230 231 // Generic absolute value. 232 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs()); 233 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs()); 234 TEST_EXPECTED_VALUE(DstLimits::max(), 235 CheckedNumeric<Dst>(DstLimits::max()).Abs()); 236 237 // Generic addition. 238 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1)); 239 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1)); 240 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1)); 241 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + 1); 242 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + 243 DstLimits::max()); 244 245 // Generic subtraction. 246 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); 247 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); 248 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); 249 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1); 250 251 // Generic multiplication. 252 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); 253 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); 254 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); 255 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); 256 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); 257 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); 258 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * 259 DstLimits::max()); 260 261 // Generic division. 262 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); 263 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 264 TEST_EXPECTED_VALUE(DstLimits::min() / 2, 265 CheckedNumeric<Dst>(DstLimits::min()) / 2); 266 TEST_EXPECTED_VALUE(DstLimits::max() / 2, 267 CheckedNumeric<Dst>(DstLimits::max()) / 2); 268 269 TestSpecializedArithmetic<Dst>(dst, line); 270 } 271 272 // Helper macro to wrap displaying the conversion types and line numbers. 273 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__) 274 275 TEST(SafeNumerics, SignedIntegerMath) { 276 TEST_ARITHMETIC(int8_t); 277 TEST_ARITHMETIC(int); 278 TEST_ARITHMETIC(intptr_t); 279 TEST_ARITHMETIC(intmax_t); 280 } 281 282 TEST(SafeNumerics, UnsignedIntegerMath) { 283 TEST_ARITHMETIC(uint8_t); 284 TEST_ARITHMETIC(unsigned int); 285 TEST_ARITHMETIC(uintptr_t); 286 TEST_ARITHMETIC(uintmax_t); 287 } 288 289 TEST(SafeNumerics, FloatingPointMath) { 290 TEST_ARITHMETIC(float); 291 TEST_ARITHMETIC(double); 292 } 293 294 // Enumerates the five different conversions types we need to test. 295 enum NumericConversionType { 296 SIGN_PRESERVING_VALUE_PRESERVING, 297 SIGN_PRESERVING_NARROW, 298 SIGN_TO_UNSIGN_WIDEN_OR_EQUAL, 299 SIGN_TO_UNSIGN_NARROW, 300 UNSIGN_TO_SIGN_NARROW_OR_EQUAL, 301 }; 302 303 // Template covering the different conversion tests. 304 template <typename Dst, typename Src, NumericConversionType conversion> 305 struct TestNumericConversion {}; 306 307 // EXPECT_EQ wrappers providing specific detail on test failures. 308 #define TEST_EXPECTED_RANGE(expected, actual) \ 309 EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ 310 << "Conversion test: " << src << " value " << actual << " to " << dst \ 311 << " on line " << line; 312 313 template <typename Dst, typename Src> 314 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { 315 static void Test(const char *dst, const char *src, int line) { 316 typedef numeric_limits<Src> SrcLimits; 317 typedef numeric_limits<Dst> DstLimits; 318 // Integral to floating. 319 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || 320 // Not floating to integral and... 321 (!(DstLimits::is_integer && SrcLimits::is_iec559) && 322 // Same sign, same numeric, source is narrower or same. 323 ((SrcLimits::is_signed == DstLimits::is_signed && 324 sizeof(Dst) >= sizeof(Src)) || 325 // Or signed destination and source is smaller 326 (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))), 327 "Comparison must be sign preserving and value preserving"); 328 329 const CheckedNumeric<Dst> checked_dst = SrcLimits::max(); 330 TEST_EXPECTED_SUCCESS(checked_dst); 331 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) { 332 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) { 333 // At least twice larger type. 334 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst); 335 336 } else { // Larger, but not at least twice as large. 337 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst); 338 TEST_EXPECTED_SUCCESS(checked_dst + 1); 339 } 340 } else { // Same width type. 341 TEST_EXPECTED_FAILURE(checked_dst + 1); 342 } 343 344 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 345 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 346 if (SrcLimits::is_iec559) { 347 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); 348 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 349 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 350 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 351 } else if (numeric_limits<Src>::is_signed) { 352 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 353 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); 354 } 355 } 356 }; 357 358 template <typename Dst, typename Src> 359 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { 360 static void Test(const char *dst, const char *src, int line) { 361 typedef numeric_limits<Src> SrcLimits; 362 typedef numeric_limits<Dst> DstLimits; 363 static_assert(SrcLimits::is_signed == DstLimits::is_signed, 364 "Destination and source sign must be the same"); 365 static_assert(sizeof(Dst) < sizeof(Src) || 366 (DstLimits::is_integer && SrcLimits::is_iec559), 367 "Destination must be narrower than source"); 368 369 const CheckedNumeric<Dst> checked_dst; 370 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 371 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 372 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max()); 373 374 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 375 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 376 if (SrcLimits::is_iec559) { 377 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 378 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 379 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 380 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 381 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 382 if (DstLimits::is_integer) { 383 if (SrcLimits::digits < DstLimits::digits) { 384 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, 385 static_cast<Src>(DstLimits::max())); 386 } else { 387 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); 388 } 389 TEST_EXPECTED_RANGE( 390 RANGE_VALID, 391 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); 392 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); 393 } 394 } else if (SrcLimits::is_signed) { 395 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); 396 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); 397 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 398 } else { 399 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1)); 400 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); 401 } 402 } 403 }; 404 405 template <typename Dst, typename Src> 406 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> { 407 static void Test(const char *dst, const char *src, int line) { 408 typedef numeric_limits<Src> SrcLimits; 409 typedef numeric_limits<Dst> DstLimits; 410 static_assert(sizeof(Dst) >= sizeof(Src), 411 "Destination must be equal or wider than source."); 412 static_assert(SrcLimits::is_signed, "Source must be signed"); 413 static_assert(!DstLimits::is_signed, "Destination must be unsigned"); 414 415 const CheckedNumeric<Dst> checked_dst; 416 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); 417 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1)); 418 TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max()); 419 420 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); 421 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 422 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 423 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 424 } 425 }; 426 427 template <typename Dst, typename Src> 428 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> { 429 static void Test(const char *dst, const char *src, int line) { 430 typedef numeric_limits<Src> SrcLimits; 431 typedef numeric_limits<Dst> DstLimits; 432 static_assert((DstLimits::is_integer && SrcLimits::is_iec559) || 433 (sizeof(Dst) < sizeof(Src)), 434 "Destination must be narrower than source."); 435 static_assert(SrcLimits::is_signed, "Source must be signed."); 436 static_assert(!DstLimits::is_signed, "Destination must be unsigned."); 437 438 const CheckedNumeric<Dst> checked_dst; 439 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 440 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 441 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1)); 442 TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max()); 443 444 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 445 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 446 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 447 if (SrcLimits::is_iec559) { 448 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 449 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 450 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 451 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 452 if (DstLimits::is_integer) { 453 if (SrcLimits::digits < DstLimits::digits) { 454 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, 455 static_cast<Src>(DstLimits::max())); 456 } else { 457 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); 458 } 459 TEST_EXPECTED_RANGE( 460 RANGE_VALID, 461 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); 462 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); 463 } 464 } else { 465 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); 466 } 467 } 468 }; 469 470 template <typename Dst, typename Src> 471 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { 472 static void Test(const char *dst, const char *src, int line) { 473 typedef numeric_limits<Src> SrcLimits; 474 typedef numeric_limits<Dst> DstLimits; 475 static_assert(sizeof(Dst) <= sizeof(Src), 476 "Destination must be narrower or equal to source."); 477 static_assert(!SrcLimits::is_signed, "Source must be unsigned."); 478 static_assert(DstLimits::is_signed, "Destination must be signed."); 479 480 const CheckedNumeric<Dst> checked_dst; 481 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 482 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 483 TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min()); 484 485 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); 486 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 487 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 488 } 489 }; 490 491 // Helper macro to wrap displaying the conversion types and line numbers 492 #define TEST_NUMERIC_CONVERSION(d, s, t) \ 493 TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__) 494 495 TEST(SafeNumerics, IntMinOperations) { 496 TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING); 497 TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); 498 499 TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW); 500 TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW); 501 TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW); 502 503 TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 504 505 TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW); 506 TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW); 507 TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW); 508 509 TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 510 TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 511 } 512 513 TEST(SafeNumerics, IntOperations) { 514 TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING); 515 TEST_NUMERIC_CONVERSION(unsigned int, unsigned int, 516 SIGN_PRESERVING_VALUE_PRESERVING); 517 TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING); 518 TEST_NUMERIC_CONVERSION(unsigned int, uint8_t, 519 SIGN_PRESERVING_VALUE_PRESERVING); 520 TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); 521 522 TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW); 523 TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW); 524 TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW); 525 TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW); 526 527 TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 528 TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 529 530 TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW); 531 TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW); 532 TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW); 533 534 TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 535 TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 536 } 537 538 TEST(SafeNumerics, IntMaxOperations) { 539 TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); 540 TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t, 541 SIGN_PRESERVING_VALUE_PRESERVING); 542 TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING); 543 TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int, 544 SIGN_PRESERVING_VALUE_PRESERVING); 545 TEST_NUMERIC_CONVERSION(intmax_t, unsigned int, 546 SIGN_PRESERVING_VALUE_PRESERVING); 547 TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); 548 549 TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW); 550 TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW); 551 552 TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 553 TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 554 555 TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW); 556 TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW); 557 558 TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 559 } 560 561 TEST(SafeNumerics, FloatOperations) { 562 TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); 563 TEST_NUMERIC_CONVERSION(float, uintmax_t, 564 SIGN_PRESERVING_VALUE_PRESERVING); 565 TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING); 566 TEST_NUMERIC_CONVERSION(float, unsigned int, 567 SIGN_PRESERVING_VALUE_PRESERVING); 568 569 TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW); 570 } 571 572 TEST(SafeNumerics, DoubleOperations) { 573 TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); 574 TEST_NUMERIC_CONVERSION(double, uintmax_t, 575 SIGN_PRESERVING_VALUE_PRESERVING); 576 TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING); 577 TEST_NUMERIC_CONVERSION(double, unsigned int, 578 SIGN_PRESERVING_VALUE_PRESERVING); 579 } 580 581 TEST(SafeNumerics, SizeTOperations) { 582 TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 583 TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 584 } 585 586 TEST(SafeNumerics, CastTests) { 587 // MSVC catches and warns that we're forcing saturation in these tests. 588 // Since that's intentional, we need to shut this warning off. 589 #if defined(COMPILER_MSVC) 590 #pragma warning(disable : 4756) 591 #endif 592 593 int small_positive = 1; 594 int small_negative = -1; 595 double double_small = 1.0; 596 double double_large = numeric_limits<double>::max(); 597 double double_infinity = numeric_limits<float>::infinity(); 598 double double_large_int = numeric_limits<int>::max(); 599 double double_small_int = numeric_limits<int>::min(); 600 601 // Just test that the casts compile, since the other tests cover logic. 602 EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0))); 603 EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0))); 604 EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0))); 605 EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0))); 606 EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U))); 607 EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U))); 608 EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U))); 609 610 EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid()); 611 EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid()); 612 EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid()); 613 614 EXPECT_TRUE(IsValueNegative(-1)); 615 EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min())); 616 EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min())); 617 EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max())); 618 EXPECT_FALSE(IsValueNegative(0)); 619 EXPECT_FALSE(IsValueNegative(1)); 620 EXPECT_FALSE(IsValueNegative(0u)); 621 EXPECT_FALSE(IsValueNegative(1u)); 622 EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max())); 623 EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max())); 624 EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max())); 625 626 // These casts and coercions will fail to compile: 627 // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0))); 628 // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0))); 629 // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1)); 630 // EXPECT_EQ(1, StrictNumeric<size_t>(1U)); 631 632 // Test various saturation corner cases. 633 EXPECT_EQ(saturated_cast<int>(small_negative), 634 static_cast<int>(small_negative)); 635 EXPECT_EQ(saturated_cast<int>(small_positive), 636 static_cast<int>(small_positive)); 637 EXPECT_EQ(saturated_cast<unsigned>(small_negative), 638 static_cast<unsigned>(0)); 639 EXPECT_EQ(saturated_cast<int>(double_small), 640 static_cast<int>(double_small)); 641 EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); 642 EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); 643 EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); 644 EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int)); 645 EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int)); 646 647 float not_a_number = std::numeric_limits<float>::infinity() - 648 std::numeric_limits<float>::infinity(); 649 EXPECT_TRUE(std::isnan(not_a_number)); 650 EXPECT_EQ(0, saturated_cast<int>(not_a_number)); 651 } 652 653 #if GTEST_HAS_DEATH_TEST 654 655 TEST(SafeNumerics, SaturatedCastChecks) { 656 float not_a_number = std::numeric_limits<float>::infinity() - 657 std::numeric_limits<float>::infinity(); 658 EXPECT_TRUE(std::isnan(not_a_number)); 659 EXPECT_DEATH((saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>( 660 not_a_number)), ""); 661 } 662 663 #endif // GTEST_HAS_DEATH_TEST 664 665 TEST(SafeNumerics, IsValueInRangeForNumericType) { 666 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0)); 667 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1)); 668 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2)); 669 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1)); 670 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu)); 671 EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff))); 672 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000))); 673 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001))); 674 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>( 675 std::numeric_limits<int32_t>::min())); 676 EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>( 677 std::numeric_limits<int64_t>::min())); 678 679 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0)); 680 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1)); 681 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2)); 682 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1)); 683 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff)); 684 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu)); 685 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u)); 686 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu)); 687 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000))); 688 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff))); 689 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000))); 690 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>( 691 std::numeric_limits<int32_t>::min())); 692 EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>( 693 static_cast<int64_t>(std::numeric_limits<int32_t>::min()))); 694 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>( 695 static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1)); 696 EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>( 697 std::numeric_limits<int64_t>::min())); 698 699 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0)); 700 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1)); 701 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2)); 702 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1)); 703 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu)); 704 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff))); 705 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000))); 706 EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001))); 707 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>( 708 std::numeric_limits<int32_t>::min())); 709 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1))); 710 EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>( 711 std::numeric_limits<int64_t>::min())); 712 713 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0)); 714 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1)); 715 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2)); 716 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1)); 717 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff)); 718 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu)); 719 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u)); 720 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu)); 721 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000))); 722 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff))); 723 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000))); 724 EXPECT_TRUE( 725 IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff))); 726 EXPECT_TRUE( 727 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff))); 728 EXPECT_FALSE( 729 IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000))); 730 EXPECT_FALSE( 731 IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff))); 732 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( 733 std::numeric_limits<int32_t>::min())); 734 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( 735 static_cast<int64_t>(std::numeric_limits<int32_t>::min()))); 736 EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>( 737 std::numeric_limits<int64_t>::min())); 738 } 739 740 TEST(SafeNumerics, CompoundNumericOperations) { 741 CheckedNumeric<int> a = 1; 742 CheckedNumeric<int> b = 2; 743 CheckedNumeric<int> c = 3; 744 CheckedNumeric<int> d = 4; 745 a += b; 746 EXPECT_EQ(3, a.ValueOrDie()); 747 a -= c; 748 EXPECT_EQ(0, a.ValueOrDie()); 749 d /= b; 750 EXPECT_EQ(2, d.ValueOrDie()); 751 d *= d; 752 EXPECT_EQ(4, d.ValueOrDie()); 753 754 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); 755 EXPECT_TRUE(too_large.IsValid()); 756 too_large += d; 757 EXPECT_FALSE(too_large.IsValid()); 758 too_large -= d; 759 EXPECT_FALSE(too_large.IsValid()); 760 too_large /= d; 761 EXPECT_FALSE(too_large.IsValid()); 762 } 763