diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-03-07 19:19:56 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-03-07 19:19:56 +0000 |
commit | bc3b24269eabf6e9e54598c82ede3c741d8a6e61 (patch) | |
tree | 05263dec97561e85f08186e318bd8b84b517f290 /unittests | |
parent | fac248734708670e898b814f88f5f262da774de3 (diff) | |
download | llvm-bc3b24269eabf6e9e54598c82ede3c741d8a6e61.tar.gz llvm-bc3b24269eabf6e9e54598c82ede3c741d8a6e61.tar.bz2 llvm-bc3b24269eabf6e9e54598c82ede3c741d8a6e61.tar.xz |
[ADT] Update PointerIntPair to handle pointer types with more than 31 bits free.
Previously, the assertions in PointerIntPair would try to calculate the value
(1 << NumLowBitsAvailable); the inferred type here is 'int', so if there were
more than 31 bits available we'd get a shift overflow.
Also, add a rudimentary unit test file for PointerIntPair.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203273 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ADT/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/ADT/PointerIntPairTest.cpp | 74 |
2 files changed, 75 insertions, 0 deletions
diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt index 88e8186f33..66e2d20ef7 100644 --- a/unittests/ADT/CMakeLists.txt +++ b/unittests/ADT/CMakeLists.txt @@ -24,6 +24,7 @@ set(ADTSources OptionalTest.cpp OwningPtrTest.cpp PackedVectorTest.cpp + PointerIntPairTest.cpp PointerUnionTest.cpp SCCIteratorTest.cpp SmallPtrSetTest.cpp diff --git a/unittests/ADT/PointerIntPairTest.cpp b/unittests/ADT/PointerIntPairTest.cpp new file mode 100644 index 0000000000..3da31e7dfe --- /dev/null +++ b/unittests/ADT/PointerIntPairTest.cpp @@ -0,0 +1,74 @@ +//===- llvm/unittest/ADT/PointerIntPairTest.cpp - Unit tests --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "llvm/ADT/PointerIntPair.h" +#include <limits> +using namespace llvm; + +namespace { + +// Test fixture +class PointerIntPairTest : public testing::Test { +}; + +TEST_F(PointerIntPairTest, GetSet) { + PointerIntPair<PointerIntPairTest *, 2> Pair{this, 1U}; + EXPECT_EQ(this, Pair.getPointer()); + EXPECT_EQ(1U, Pair.getInt()); + + Pair.setInt(2); + EXPECT_EQ(this, Pair.getPointer()); + EXPECT_EQ(2U, Pair.getInt()); + + Pair.setPointer(nullptr); + EXPECT_EQ(nullptr, Pair.getPointer()); + EXPECT_EQ(2U, Pair.getInt()); + + Pair.setPointerAndInt(this, 3U); + EXPECT_EQ(this, Pair.getPointer()); + EXPECT_EQ(3U, Pair.getInt()); +} + +TEST_F(PointerIntPairTest, DefaultInitialize) { + PointerIntPair<PointerIntPairTest *, 2> Pair; + EXPECT_EQ(nullptr, Pair.getPointer()); + EXPECT_EQ(0U, Pair.getInt()); +} + +TEST_F(PointerIntPairTest, ManyUnusedBits) { + // In real code this would be a word-sized integer limited to 31 bits. + struct Fixnum31 { + uintptr_t Value; + }; + class FixnumPointerTraits { + public: + static inline void *getAsVoidPointer(Fixnum31 Num) { + return reinterpret_cast<void *>(Num.Value << NumLowBitsAvailable); + } + static inline Fixnum31 getFromVoidPointer(void *P) { + // In real code this would assert that the value is in range. + return { reinterpret_cast<uintptr_t>(P) >> NumLowBitsAvailable }; + } + enum { NumLowBitsAvailable = std::numeric_limits<uintptr_t>::digits - 31 }; + }; + + PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits> pair; + EXPECT_EQ((uintptr_t)0, pair.getPointer().Value); + EXPECT_EQ(false, pair.getInt()); + + pair.setPointerAndInt({ 0x7FFFFFFF }, true ); + EXPECT_EQ((uintptr_t)0x7FFFFFFF, pair.getPointer().Value); + EXPECT_EQ(true, pair.getInt()); + + EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1, + PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable); +} + +} // end anonymous namespace |