diff options
author | JF Bastien <jfbastien@apple.com> | 2019-07-31 19:40:07 +0000 |
---|---|---|
committer | JF Bastien <jfbastien@apple.com> | 2019-07-31 19:40:07 +0000 |
commit | fe968c3639539ddd73c506cd3332dc0a086a3924 (patch) | |
tree | 7a68ad59ae65e56e974af329c579f6ee8dd342b4 /llvm/unittests/Support/MathExtrasTest.cpp | |
parent | f724b460bd9bf616a2856e416a71fcbc36f839de (diff) | |
download | bcm5719-llvm-fe968c3639539ddd73c506cd3332dc0a086a3924.tar.gz bcm5719-llvm-fe968c3639539ddd73c506cd3332dc0a086a3924.zip |
[Support] Added overflow checking add, sub and mul.
Added AddOverflow, SubOverflow and MulOverflow to compute truncated results and return a flag indicating whether overflow occured.
Differential Revision: https://reviews.llvm.org/D65494
llvm-svn: 367470
Diffstat (limited to 'llvm/unittests/Support/MathExtrasTest.cpp')
-rw-r--r-- | llvm/unittests/Support/MathExtrasTest.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp index de8771402fb..01c83c9e14d 100644 --- a/llvm/unittests/Support/MathExtrasTest.cpp +++ b/llvm/unittests/Support/MathExtrasTest.cpp @@ -468,4 +468,131 @@ TEST(MathExtras, IsShiftedInt) { EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15))); } +template <typename T> +class OverflowTest : public ::testing::Test { }; + +using OverflowTestTypes = ::testing::Types<signed char, short, int, long, + long long>; + +TYPED_TEST_CASE(OverflowTest, OverflowTestTypes); + +TYPED_TEST(OverflowTest, AddNoOverflow) { + TypeParam Result; + EXPECT_FALSE(AddOverflow<TypeParam>(1, 2, Result)); + EXPECT_EQ(Result, TypeParam(3)); +} + +TYPED_TEST(OverflowTest, AddOverflowToNegative) { + TypeParam Result; + auto MaxValue = std::numeric_limits<TypeParam>::max(); + EXPECT_TRUE(AddOverflow<TypeParam>(MaxValue, MaxValue, Result)); + EXPECT_EQ(Result, TypeParam(-2)); +} + +TYPED_TEST(OverflowTest, AddOverflowToMin) { + TypeParam Result; + auto MaxValue = std::numeric_limits<TypeParam>::max(); + EXPECT_TRUE(AddOverflow<TypeParam>(MaxValue, TypeParam(1), Result)); + EXPECT_EQ(Result, std::numeric_limits<TypeParam>::min()); +} + +TYPED_TEST(OverflowTest, AddOverflowToZero) { + TypeParam Result; + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(AddOverflow<TypeParam>(MinValue, MinValue, Result)); + EXPECT_EQ(Result, TypeParam(0)); +} + +TYPED_TEST(OverflowTest, AddOverflowToMax) { + TypeParam Result; + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(AddOverflow<TypeParam>(MinValue, TypeParam(-1), Result)); + EXPECT_EQ(Result, std::numeric_limits<TypeParam>::max()); +} + +TYPED_TEST(OverflowTest, SubNoOverflow) { + TypeParam Result; + EXPECT_FALSE(SubOverflow<TypeParam>(1, 2, Result)); + EXPECT_EQ(Result, TypeParam(-1)); +} + +TYPED_TEST(OverflowTest, SubOverflowToMax) { + TypeParam Result; + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(SubOverflow<TypeParam>(0, MinValue, Result)); + EXPECT_EQ(Result, MinValue); +} + +TYPED_TEST(OverflowTest, SubOverflowToMin) { + TypeParam Result; + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(SubOverflow<TypeParam>(0, MinValue, Result)); + EXPECT_EQ(Result, MinValue); +} + +TYPED_TEST(OverflowTest, SubOverflowToNegative) { + TypeParam Result; + auto MaxValue = std::numeric_limits<TypeParam>::max(); + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(SubOverflow<TypeParam>(MaxValue, MinValue, Result)); + EXPECT_EQ(Result, TypeParam(-1)); +} + +TYPED_TEST(OverflowTest, SubOverflowToPositive) { + TypeParam Result; + auto MaxValue = std::numeric_limits<TypeParam>::max(); + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(SubOverflow<TypeParam>(MinValue, MaxValue, Result)); + EXPECT_EQ(Result, TypeParam(1)); +} + +TYPED_TEST(OverflowTest, MulNoOverflow) { + TypeParam Result; + EXPECT_FALSE(MulOverflow<TypeParam>(1, 2, Result)); + EXPECT_EQ(Result, 2); + EXPECT_FALSE(MulOverflow<TypeParam>(-1, 3, Result)); + EXPECT_EQ(Result, -3); + EXPECT_FALSE(MulOverflow<TypeParam>(4, -2, Result)); + EXPECT_EQ(Result, -8); + EXPECT_FALSE(MulOverflow<TypeParam>(-6, -5, Result)); + EXPECT_EQ(Result, 30); +} + +TYPED_TEST(OverflowTest, MulNoOverflowToMax) { + TypeParam Result; + auto MaxValue = std::numeric_limits<TypeParam>::max(); + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_FALSE(MulOverflow<TypeParam>(MinValue + 1, -1, Result)); + EXPECT_EQ(Result, MaxValue); +} + +TYPED_TEST(OverflowTest, MulOverflowToMin) { + TypeParam Result; + auto MinValue = std::numeric_limits<TypeParam>::min(); + EXPECT_TRUE(MulOverflow<TypeParam>(MinValue, -1, Result)); + EXPECT_EQ(Result, MinValue); +} + +TYPED_TEST(OverflowTest, MulOverflowMax) { + TypeParam Result; + auto MinValue = std::numeric_limits<TypeParam>::min(); + auto MaxValue = std::numeric_limits<TypeParam>::max(); + EXPECT_TRUE(MulOverflow<TypeParam>(MinValue, MinValue, Result)); + EXPECT_EQ(Result, 0); + EXPECT_TRUE(MulOverflow<TypeParam>(MaxValue, MaxValue, Result)); + EXPECT_EQ(Result, 1); +} + +TYPED_TEST(OverflowTest, MulResultZero) { + TypeParam Result; + EXPECT_FALSE(MulOverflow<TypeParam>(4, 0, Result)); + EXPECT_EQ(Result, TypeParam(0)); + EXPECT_FALSE(MulOverflow<TypeParam>(-5, 0, Result)); + EXPECT_EQ(Result, TypeParam(0)); + EXPECT_FALSE(MulOverflow<TypeParam>(0, 5, Result)); + EXPECT_EQ(Result, TypeParam(0)); + EXPECT_FALSE(MulOverflow<TypeParam>(0, -5, Result)); + EXPECT_EQ(Result, TypeParam(0)); +} + } // namespace |