Skip to content

Commit

Permalink
Add assertions checking SignExtend{32,64}'s bit width.
Browse files Browse the repository at this point in the history
Summary:
The bit width must be greater than zero, otherwise we shift by the
integer's width, which is UB.  Also (more obviously) the width must be
less than or equal to the integer's width, otherwise we shift by a
negative number, which is also UB.

Reviewers: rnk

Subscribers: llvm-commits, dylanmckay

Differential Revision: https://reviews.llvm.org/D22442

llvm-svn: 275720
  • Loading branch information
Justin Lebar committed Jul 17, 2016
1 parent cbba3c4 commit ab549c8
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions llvm/include/llvm/Support/MathExtras.h
Expand Up @@ -672,27 +672,35 @@ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
return alignTo(Value, Align) - Value;
}

/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
/// Usage int32_t r = SignExtend32<5>(x);
template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
return int32_t(x << (32 - B)) >> (32 - B);
/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
/// Requires 0 < B <= 32.
template <unsigned B> inline int32_t SignExtend32(uint32_t X) {
static_assert(B > 0, "Bit width can't be 0.");
static_assert(B <= 32, "Bit width out of range.");
return int32_t(X << (32 - B)) >> (32 - B);
}

/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
/// Requires 0 < B <= 32.
/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
/// Requires 0 < B < 32.
inline int32_t SignExtend32(uint32_t X, unsigned B) {
assert(B > 0 && "Bit width can't be 0.");
assert(B <= 32 && "Bit width out of range.");
return int32_t(X << (32 - B)) >> (32 - B);
}

/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
/// Usage int64_t r = SignExtend64<5>(x);
/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
/// Requires 0 < B < 64.
template <unsigned B> inline int64_t SignExtend64(uint64_t x) {
static_assert(B > 0, "Bit width can't be 0.");
static_assert(B <= 64, "Bit width out of range.");
return int64_t(x << (64 - B)) >> (64 - B);
}

/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
/// Requires 0 < B <= 64.
/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
/// Requires 0 < B < 64.
inline int64_t SignExtend64(uint64_t X, unsigned B) {
assert(B > 0 && "Bit width can't be 0.");
assert(B <= 64 && "Bit width out of range.");
return int64_t(X << (64 - B)) >> (64 - B);
}

Expand Down

0 comments on commit ab549c8

Please sign in to comment.