summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Support/MathExtrasTest.cpp
diff options
context:
space:
mode:
authorJF Bastien <jfbastien@apple.com>2019-07-31 19:40:07 +0000
committerJF Bastien <jfbastien@apple.com>2019-07-31 19:40:07 +0000
commitfe968c3639539ddd73c506cd3332dc0a086a3924 (patch)
tree7a68ad59ae65e56e974af329c579f6ee8dd342b4 /llvm/unittests/Support/MathExtrasTest.cpp
parentf724b460bd9bf616a2856e416a71fcbc36f839de (diff)
downloadbcm5719-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.cpp127
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
OpenPOWER on IntegriCloud