[llvm] r300721 - [MathExtras] Fix undefined behavior (shift by bit width)

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 19 10:46:16 PDT 2017


Author: d0k
Date: Wed Apr 19 12:46:15 2017
New Revision: 300721

URL: http://llvm.org/viewvc/llvm-project?rev=300721&view=rev
Log:
[MathExtras] Fix undefined behavior (shift by bit width)

While there add some unit tests for uint64_t. Found by ubsan.

Modified:
    llvm/trunk/include/llvm/Support/MathExtras.h
    llvm/trunk/unittests/Support/MathExtrasTest.cpp

Modified: llvm/trunk/include/llvm/Support/MathExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MathExtras.h?rev=300721&r1=300720&r2=300721&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/MathExtras.h (original)
+++ llvm/trunk/include/llvm/Support/MathExtras.h Wed Apr 19 12:46:15 2017
@@ -205,7 +205,7 @@ template <typename T> T maskTrailingOnes
   static_assert(std::is_unsigned<T>::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

Modified: llvm/trunk/unittests/Support/MathExtrasTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/MathExtrasTest.cpp?rev=300721&r1=300720&r2=300721&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/MathExtrasTest.cpp (original)
+++ llvm/trunk/unittests/Support/MathExtrasTest.cpp Wed Apr 19 12:46:15 2017
@@ -84,6 +84,11 @@ TEST(MathExtras, onesMask) {
 
   EXPECT_EQ(0xFFFFFFFFU, maskTrailingOnes<uint32_t>(32U));
   EXPECT_EQ(0xFFFFFFFFU, maskLeadingOnes<uint32_t>(32U));
+  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, maskTrailingOnes<uint64_t>(64U));
+  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, maskLeadingOnes<uint64_t>(64U));
+
+  EXPECT_EQ(0x0000FFFFFFFFFFFFULL, maskTrailingOnes<uint64_t>(48U));
+  EXPECT_EQ(0xFFFFFFFFFFFF0000ULL, maskLeadingOnes<uint64_t>(48U));
 }
 
 TEST(MathExtras, findFirstSet) {




More information about the llvm-commits mailing list