diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2014-03-15 18:10:49 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2014-03-15 18:10:49 +0000 |
commit | 80d3b1e7087421008df3c6794b60beaf395efbeb (patch) | |
tree | 4cc4a5baba44fe9d56fe8620973b22ffb6fd2f28 /include | |
parent | 14029414f51301c8543710ffd8f7c8c1e53789fe (diff) | |
download | llvm-80d3b1e7087421008df3c6794b60beaf395efbeb.tar.gz llvm-80d3b1e7087421008df3c6794b60beaf395efbeb.tar.bz2 llvm-80d3b1e7087421008df3c6794b60beaf395efbeb.tar.xz |
PointerIntPair: Avoid an (academic) case of undefined behavior in the DenseMapInfo specialization.
If we use a pair with an enum type this could create values outside
of the enum range. Avoid it by creating the bit pattern directly.
While there turn a dynamic assert into a static one. No functionality
change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204010 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/ADT/PointerIntPair.h | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 313abf3a14..45a40db85c 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -45,6 +45,8 @@ class PointerIntPair { static_assert(PtrTraits::NumLowBitsAvailable < std::numeric_limits<uintptr_t>::digits, "cannot use a pointer type that has all bits free"); + static_assert(IntBits <= PtrTraits::NumLowBitsAvailable, + "PointerIntPair with integer size too large for pointer"); enum : uintptr_t { /// PointerBitMask - The bits that come from the pointer. PointerBitMask = @@ -63,8 +65,6 @@ class PointerIntPair { public: PointerIntPair() : Value(0) {} PointerIntPair(PointerTy PtrVal, IntType IntVal) { - assert(IntBits <= PtrTraits::NumLowBitsAvailable && - "PointerIntPair formed with integer size too large for pointer"); setPointerAndInt(PtrVal, IntVal); } explicit PointerIntPair(PointerTy PtrVal) { @@ -162,13 +162,13 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > { typedef PointerIntPair<PointerTy, IntBits, IntType> Ty; static Ty getEmptyKey() { uintptr_t Val = static_cast<uintptr_t>(-1); - Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable; - return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1)); + Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable; + return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val)); } static Ty getTombstoneKey() { uintptr_t Val = static_cast<uintptr_t>(-2); Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable; - return Ty(reinterpret_cast<PointerTy>(Val), IntType(0)); + return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val)); } static unsigned getHashValue(Ty V) { uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue()); |