From fe968c3639539ddd73c506cd3332dc0a086a3924 Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Wed, 31 Jul 2019 19:40:07 +0000 Subject: [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 --- llvm/unittests/Support/MathExtrasTest.cpp | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) (limited to 'llvm/unittests/Support/MathExtrasTest.cpp') 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 +class OverflowTest : public ::testing::Test { }; + +using OverflowTestTypes = ::testing::Types; + +TYPED_TEST_CASE(OverflowTest, OverflowTestTypes); + +TYPED_TEST(OverflowTest, AddNoOverflow) { + TypeParam Result; + EXPECT_FALSE(AddOverflow(1, 2, Result)); + EXPECT_EQ(Result, TypeParam(3)); +} + +TYPED_TEST(OverflowTest, AddOverflowToNegative) { + TypeParam Result; + auto MaxValue = std::numeric_limits::max(); + EXPECT_TRUE(AddOverflow(MaxValue, MaxValue, Result)); + EXPECT_EQ(Result, TypeParam(-2)); +} + +TYPED_TEST(OverflowTest, AddOverflowToMin) { + TypeParam Result; + auto MaxValue = std::numeric_limits::max(); + EXPECT_TRUE(AddOverflow(MaxValue, TypeParam(1), Result)); + EXPECT_EQ(Result, std::numeric_limits::min()); +} + +TYPED_TEST(OverflowTest, AddOverflowToZero) { + TypeParam Result; + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(AddOverflow(MinValue, MinValue, Result)); + EXPECT_EQ(Result, TypeParam(0)); +} + +TYPED_TEST(OverflowTest, AddOverflowToMax) { + TypeParam Result; + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(AddOverflow(MinValue, TypeParam(-1), Result)); + EXPECT_EQ(Result, std::numeric_limits::max()); +} + +TYPED_TEST(OverflowTest, SubNoOverflow) { + TypeParam Result; + EXPECT_FALSE(SubOverflow(1, 2, Result)); + EXPECT_EQ(Result, TypeParam(-1)); +} + +TYPED_TEST(OverflowTest, SubOverflowToMax) { + TypeParam Result; + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(SubOverflow(0, MinValue, Result)); + EXPECT_EQ(Result, MinValue); +} + +TYPED_TEST(OverflowTest, SubOverflowToMin) { + TypeParam Result; + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(SubOverflow(0, MinValue, Result)); + EXPECT_EQ(Result, MinValue); +} + +TYPED_TEST(OverflowTest, SubOverflowToNegative) { + TypeParam Result; + auto MaxValue = std::numeric_limits::max(); + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(SubOverflow(MaxValue, MinValue, Result)); + EXPECT_EQ(Result, TypeParam(-1)); +} + +TYPED_TEST(OverflowTest, SubOverflowToPositive) { + TypeParam Result; + auto MaxValue = std::numeric_limits::max(); + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(SubOverflow(MinValue, MaxValue, Result)); + EXPECT_EQ(Result, TypeParam(1)); +} + +TYPED_TEST(OverflowTest, MulNoOverflow) { + TypeParam Result; + EXPECT_FALSE(MulOverflow(1, 2, Result)); + EXPECT_EQ(Result, 2); + EXPECT_FALSE(MulOverflow(-1, 3, Result)); + EXPECT_EQ(Result, -3); + EXPECT_FALSE(MulOverflow(4, -2, Result)); + EXPECT_EQ(Result, -8); + EXPECT_FALSE(MulOverflow(-6, -5, Result)); + EXPECT_EQ(Result, 30); +} + +TYPED_TEST(OverflowTest, MulNoOverflowToMax) { + TypeParam Result; + auto MaxValue = std::numeric_limits::max(); + auto MinValue = std::numeric_limits::min(); + EXPECT_FALSE(MulOverflow(MinValue + 1, -1, Result)); + EXPECT_EQ(Result, MaxValue); +} + +TYPED_TEST(OverflowTest, MulOverflowToMin) { + TypeParam Result; + auto MinValue = std::numeric_limits::min(); + EXPECT_TRUE(MulOverflow(MinValue, -1, Result)); + EXPECT_EQ(Result, MinValue); +} + +TYPED_TEST(OverflowTest, MulOverflowMax) { + TypeParam Result; + auto MinValue = std::numeric_limits::min(); + auto MaxValue = std::numeric_limits::max(); + EXPECT_TRUE(MulOverflow(MinValue, MinValue, Result)); + EXPECT_EQ(Result, 0); + EXPECT_TRUE(MulOverflow(MaxValue, MaxValue, Result)); + EXPECT_EQ(Result, 1); +} + +TYPED_TEST(OverflowTest, MulResultZero) { + TypeParam Result; + EXPECT_FALSE(MulOverflow(4, 0, Result)); + EXPECT_EQ(Result, TypeParam(0)); + EXPECT_FALSE(MulOverflow(-5, 0, Result)); + EXPECT_EQ(Result, TypeParam(0)); + EXPECT_FALSE(MulOverflow(0, 5, Result)); + EXPECT_EQ(Result, TypeParam(0)); + EXPECT_FALSE(MulOverflow(0, -5, Result)); + EXPECT_EQ(Result, TypeParam(0)); +} + } // namespace -- cgit v1.2.3