diff options
Diffstat (limited to 'libc/test/src/__support/math_extras_test.cpp')
-rw-r--r-- | libc/test/src/__support/math_extras_test.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/libc/test/src/__support/math_extras_test.cpp b/libc/test/src/__support/math_extras_test.cpp index e88b3e1d6b68..401e631ea4ba 100644 --- a/libc/test/src/__support/math_extras_test.cpp +++ b/libc/test/src/__support/math_extras_test.cpp @@ -101,4 +101,61 @@ TYPED_TEST(LlvmLibcBitTest, CountZeros, UnsignedTypesNoBigInt) { EXPECT_EQ(count_zeros<T>(cpp::numeric_limits<T>::max() >> i), i); } +using UnsignedTypes = testing::TypeList< +#if defined(__SIZEOF_INT128__) + __uint128_t, +#endif + unsigned char, unsigned short, unsigned int, unsigned long, + unsigned long long>; + +TYPED_TEST(LlvmLibcBlockMathExtrasTest, add_overflow, UnsignedTypes) { + constexpr T ZERO = cpp::numeric_limits<T>::min(); + constexpr T ONE(1); + constexpr T MAX = cpp::numeric_limits<T>::max(); + constexpr T BEFORE_MAX = MAX - 1; + + const struct { + T lhs; + T rhs; + T sum; + bool carry; + } TESTS[] = { + {ZERO, ONE, ONE, false}, // 0x00 + 0x01 = 0x01 + {BEFORE_MAX, ONE, MAX, false}, // 0xFE + 0x01 = 0xFF + {MAX, ONE, ZERO, true}, // 0xFF + 0x01 = 0x00 (carry) + {MAX, MAX, BEFORE_MAX, true}, // 0xFF + 0xFF = 0xFE (carry) + }; + for (auto tc : TESTS) { + T sum; + bool carry = add_overflow<T>(tc.lhs, tc.rhs, sum); + EXPECT_EQ(sum, tc.sum); + EXPECT_EQ(carry, tc.carry); + } +} + +TYPED_TEST(LlvmLibcBlockMathExtrasTest, sub_overflow, UnsignedTypes) { + constexpr T ZERO = cpp::numeric_limits<T>::min(); + constexpr T ONE(1); + constexpr T MAX = cpp::numeric_limits<T>::max(); + constexpr T BEFORE_MAX = MAX - 1; + + const struct { + T lhs; + T rhs; + T sub; + bool carry; + } TESTS[] = { + {ONE, ZERO, ONE, false}, // 0x01 - 0x00 = 0x01 + {MAX, MAX, ZERO, false}, // 0xFF - 0xFF = 0x00 + {ZERO, ONE, MAX, true}, // 0x00 - 0x01 = 0xFF (carry) + {BEFORE_MAX, MAX, MAX, true}, // 0xFE - 0xFF = 0xFF (carry) + }; + for (auto tc : TESTS) { + T sub; + bool carry = sub_overflow<T>(tc.lhs, tc.rhs, sub); + EXPECT_EQ(sub, tc.sub); + EXPECT_EQ(carry, tc.carry); + } +} + } // namespace LIBC_NAMESPACE |