15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <mmintrin.h> 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdint.h> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <limits> 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/compiler_specific.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/numerics/safe_conversions.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/numerics/safe_math.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/template_util.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using std::numeric_limits; 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::CheckedNumeric; 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::checked_cast; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::saturated_cast; 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::internal::MaxExponent; 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::internal::RANGE_VALID; 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::internal::RANGE_INVALID; 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::internal::RANGE_OVERFLOW; 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::internal::RANGE_UNDERFLOW; 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::enable_if; 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// MSVS 2013 ia32 may not reset the FPU between calculations, and the test 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// framework masks the exceptions. So we just force a manual reset after NaN. 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)inline void ResetFloatingPointUnit() { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) _mm_empty(); 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// These tests deliberately cause arithmetic overflows. If the compiler is 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// aggressive enough, it can const fold these overflows. Disable warnings about 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// overflows for const expressions. 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(OS_WIN) 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#pragma warning(disable:4756) 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Helper macros to wrap displaying the conversion types and line numbers. 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define TEST_EXPECTED_VALIDITY(expected, actual) \ 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \ 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " on line " << line; 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define TEST_EXPECTED_VALUE(expected, actual) \ 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(static_cast<Dst>(expected), \ 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(actual).ValueUnsafe()) \ 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " on line " << line; 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Signed integer arithmetic. 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Dst> 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void TestSpecializedArithmetic( 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* dst, 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int line, 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typename enable_if< 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) numeric_limits<Dst>::is_integer&& numeric_limits<Dst>::is_signed, 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int>::type = 0) { 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) -CheckedNumeric<Dst>(DstLimits::min())); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()).Abs()); 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()) + -1); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) + -1); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_UNDERFLOW, 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max()); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) - 1); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) - -1); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_OVERFLOW, 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max()); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_UNDERFLOW, 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max()); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) * 2); 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) / -1); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Modulus is legal only for integers. 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_INVALID, CheckedNumeric<Dst>(-1) % -2); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Test all the different modulus combinations. 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst> checked_dst = 1; 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, checked_dst %= 1); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Unsigned integer arithmetic. 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Dst> 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void TestSpecializedArithmetic( 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* dst, 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int line, 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typename enable_if< 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) numeric_limits<Dst>::is_integer && !numeric_limits<Dst>::is_signed, 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int>::type = 0) { 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min())); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()).Abs()); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) + -1); 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) - 1); 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Modulus is legal only for integers. 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2); 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Test all the different modulus combinations. 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst> checked_dst = 1; 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, checked_dst %= 1); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Floating point arithmetic. 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Dst> 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TestSpecializedArithmetic( 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* dst, 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int line, 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typename enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min())); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()).Abs()); 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) + -1); 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()) + 1); 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_UNDERFLOW, 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max()); 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_OVERFLOW, 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max()); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_UNDERFLOW, 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max()); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) * 2); 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating()); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Generic arithmetic tests. 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Dst> 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void TestArithmetic(const char* dst, int line) { 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid()); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(false, 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DstLimits::max()).IsValid()); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie()); 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1)); 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(static_cast<Dst>(1), 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DstLimits::max()).ValueOrDefault(1)); 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Test the operator combinations. 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1)); 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1)); 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1)); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1)); 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1)); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1)); 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1)); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1)); 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1); 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1); 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1); 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst> checked_dst = 1; 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(2, checked_dst += 1); 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) checked_dst = 1; 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, checked_dst -= 1); 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) checked_dst = 1; 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, checked_dst *= 1); 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) checked_dst = 1; 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, checked_dst /= 1); 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Generic negation. 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>()); 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1)); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1)); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1), 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) -CheckedNumeric<Dst>(DstLimits::max())); 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Generic absolute value. 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs()); 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs()); 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(DstLimits::max(), 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()).Abs()); 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Generic addition. 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1)); 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1)); 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1)); 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) + 1); 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_OVERFLOW, CheckedNumeric<Dst>(DstLimits::max()) + DstLimits::max()); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Generic subtraction. 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()) - 1); 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Generic multiplication. 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY( 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RANGE_OVERFLOW, CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max()); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Generic division. 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(DstLimits::min() / 2, 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::min()) / 2); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(DstLimits::max() / 2, 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CheckedNumeric<Dst>(DstLimits::max()) / 2); 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestSpecializedArithmetic<Dst>(dst, line); 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Helper macro to wrap displaying the conversion types and line numbers. 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__) 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, SignedIntegerMath) { 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(int8_t); 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(int); 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(intptr_t); 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(intmax_t); 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, UnsignedIntegerMath) { 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(uint8_t); 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(unsigned int); 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(uintptr_t); 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(uintmax_t); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, FloatingPointMath) { 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(float); 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_ARITHMETIC(double); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Enumerates the five different conversions types we need to test. 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum NumericConversionType { 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING, 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_NARROW, 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_TO_UNSIGN_WIDEN_OR_EQUAL, 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_TO_UNSIGN_NARROW, 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UNSIGN_TO_SIGN_NARROW_OR_EQUAL, 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Template covering the different conversion tests. 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename Dst, typename Src, NumericConversionType conversion> 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestNumericConversion {}; 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// EXPECT_EQ wrappers providing specific detail on test failures. 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define TEST_EXPECTED_RANGE(expected, actual) \ 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \ 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Conversion test: " << src << " value " << actual << " to " << dst \ 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " on line " << line; 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename Dst, typename Src> 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void Test(const char *dst, const char *src, int line) { 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Src> SrcLimits; 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Integral to floating. 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT((DstLimits::is_iec559 && SrcLimits::is_integer) || 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Not floating to integral and... 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (!(DstLimits::is_integer && SrcLimits::is_iec559) && 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Same sign, same numeric, source is narrower or same. 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ((SrcLimits::is_signed == DstLimits::is_signed && 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(Dst) >= sizeof(Src)) || 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Or signed destination and source is smaller 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))), 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) comparison_must_be_sign_preserving_and_value_preserving); 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CheckedNumeric<Dst> checked_dst = SrcLimits::max(); 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ; 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst); 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (MaxExponent<Dst>::value > MaxExponent<Src>::value) { 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) { 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // At least twice larger type. 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, SrcLimits::max() * checked_dst); 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { // Larger, but not at least twice as large. 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, SrcLimits::max() * checked_dst); 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst + 1); 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { // Same width type. 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + 1); 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (SrcLimits::is_iec559) { 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResetFloatingPointUnit(); 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (numeric_limits<Src>::is_signed) { 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename Dst, typename Src> 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void Test(const char *dst, const char *src, int line) { 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Src> SrcLimits; 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(SrcLimits::is_signed == DstLimits::is_signed, 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination_and_source_sign_must_be_the_same); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(sizeof(Dst) < sizeof(Src) || 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (DstLimits::is_integer && SrcLimits::is_iec559), 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination_must_be_narrower_than_source); 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CheckedNumeric<Dst> checked_dst; 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max()); 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); 367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (SrcLimits::is_iec559) { 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResetFloatingPointUnit(); 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (SrcLimits::is_signed) { 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename Dst, typename Src> 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> { 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void Test(const char *dst, const char *src, int line) { 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Src> SrcLimits; 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(sizeof(Dst) >= sizeof(Src), 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination_must_be_equal_or_wider_than_source); 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(SrcLimits::is_signed, source_must_be_signed); 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(!DstLimits::is_signed, destination_must_be_unsigned); 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CheckedNumeric<Dst> checked_dst; 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); 400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + static_cast<Src>(-1)); 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename Dst, typename Src> 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> { 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void Test(const char *dst, const char *src, int line) { 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Src> SrcLimits; 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT((DstLimits::is_integer && SrcLimits::is_iec559) || 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (sizeof(Dst) < sizeof(Src)), 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination_must_be_narrower_than_source); 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(SrcLimits::is_signed, source_must_be_signed); 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(!DstLimits::is_signed, destination_must_be_unsigned); 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CheckedNumeric<Dst> checked_dst; 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max()); 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + static_cast<Src>(-1)); 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); 426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (SrcLimits::is_iec559) { 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResetFloatingPointUnit(); 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename Dst, typename Src> 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void Test(const char *dst, const char *src, int line) { 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Src> SrcLimits; 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef numeric_limits<Dst> DstLimits; 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(sizeof(Dst) <= sizeof(Src), 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination_must_be_narrower_or_equal_to_source); 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(!SrcLimits::is_signed, source_must_be_unsigned); 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) COMPILE_ASSERT(DstLimits::is_signed, destination_must_be_signed); 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CheckedNumeric<Dst> checked_dst; 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max()); 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min()); 456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Helper macro to wrap displaying the conversion types and line numbers 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define TEST_NUMERIC_CONVERSION(d, s, t) \ 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__) 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, IntMinOperations) { 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING); 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW); 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW); 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW); 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW); 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW); 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW); 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, IntOperations) { 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING); 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, unsigned int, 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING); 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, uint8_t, 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW); 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW); 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW); 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW); 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW); 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW); 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, IntMaxOperations) { 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t, 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING); 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int, 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, unsigned int, 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW); 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW); 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW); 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, FloatOperations) { 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(float, uintmax_t, 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING); 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(float, unsigned int, 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW); 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, DoubleOperations) { 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(double, uintmax_t, 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING); 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(double, unsigned int, 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SIGN_PRESERVING_VALUE_PRESERVING); 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SafeNumerics, SizeTOperations) { 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(SafeNumerics, CastTests) { 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MSVC catches and warns that we're forcing saturation in these tests. 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Since that's intentional, we need to shut this warning off. 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(COMPILER_MSVC) 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#pragma warning(disable : 4756) 5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int small_positive = 1; 5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int small_negative = -1; 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) double double_small = 1.0; 568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) double double_large = numeric_limits<double>::max(); 569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) double double_infinity = numeric_limits<float>::infinity(); 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Just test that the cast compiles, since the other tests cover logic. 572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0))); 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Test various saturation corner cases. 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saturated_cast<int>(small_negative), 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<int>(small_negative)); 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saturated_cast<int>(small_positive), 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<int>(small_positive)); 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saturated_cast<unsigned>(small_negative), 5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<unsigned>(0)); 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saturated_cast<int>(double_small), 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<int>(double_small)); 583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max()); 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saturated_cast<float>(double_large), double_infinity); 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity); 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 588