From 5c42a4d473be79c68ce520701b04ce125d60515b Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 19 Apr 2017 17:46:15 +0000 Subject: [PATCH] [MathExtras] Fix undefined behavior (shift by bit width) While there add some unit tests for uint64_t. Found by ubsan. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300721 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/MathExtras.h | 2 +- unittests/Support/MathExtrasTest.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index b5b605f1893..994456f9a68 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -205,7 +205,7 @@ template T maskTrailingOnes(unsigned N) { static_assert(std::is_unsigned::value, "Invalid type!"); const unsigned Bits = CHAR_BIT * sizeof(T); assert(N <= Bits && "Invalid bit index"); - return -T(N != 0) & (T(-1) >> (Bits - N)); + return N == 0 ? 0 : (T(-1) >> (Bits - N)); } /// \brief Create a bitmask with the N left-most bits set to 1, and all other diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp index de827217083..f46d94e9e57 100644 --- a/unittests/Support/MathExtrasTest.cpp +++ b/unittests/Support/MathExtrasTest.cpp @@ -84,6 +84,11 @@ TEST(MathExtras, onesMask) { EXPECT_EQ(0xFFFFFFFFU, maskTrailingOnes(32U)); EXPECT_EQ(0xFFFFFFFFU, maskLeadingOnes(32U)); + EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, maskTrailingOnes(64U)); + EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, maskLeadingOnes(64U)); + + EXPECT_EQ(0x0000FFFFFFFFFFFFULL, maskTrailingOnes(48U)); + EXPECT_EQ(0xFFFFFFFFFFFF0000ULL, maskLeadingOnes(48U)); } TEST(MathExtras, findFirstSet) { -- 2.50.1