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

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

llvm-svn: 300721
This commit is contained in:
Benjamin Kramer 2017-04-19 17:46:15 +00:00
parent 6cb7b8a42f
commit e25268de9d
2 changed files with 6 additions and 1 deletions

View File

@ -205,7 +205,7 @@ template <typename T> T maskTrailingOnes(unsigned N) {
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

View File

@ -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) {