diff options
Diffstat (limited to 'unittests')
46 files changed, 2316 insertions, 672 deletions
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 89b8aa9..49d7e70 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -171,6 +171,34 @@ TEST(APIntTest, i1) { EXPECT_EQ(zero, neg_one.srem(one)); EXPECT_EQ(zero, neg_one.urem(one)); EXPECT_EQ(zero, one.srem(neg_one)); + + // sdivrem + { + APInt q(8, 0); + APInt r(8, 0); + APInt one(8, 1); + APInt two(8, 2); + APInt nine(8, 9); + APInt four(8, 4); + + EXPECT_EQ(nine.srem(two), one); + EXPECT_EQ(nine.srem(-two), one); + EXPECT_EQ((-nine).srem(two), -one); + EXPECT_EQ((-nine).srem(-two), -one); + + APInt::sdivrem(nine, two, q, r); + EXPECT_EQ(four, q); + EXPECT_EQ(one, r); + APInt::sdivrem(-nine, two, q, r); + EXPECT_EQ(-four, q); + EXPECT_EQ(-one, r); + APInt::sdivrem(nine, -two, q, r); + EXPECT_EQ(-four, q); + EXPECT_EQ(one, r); + APInt::sdivrem(-nine, -two, q, r); + EXPECT_EQ(four, q); + EXPECT_EQ(-one, r); + } } TEST(APIntTest, fromString) { diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp index f733e13..d836036 100644 --- a/unittests/ADT/BitVectorTest.cpp +++ b/unittests/ADT/BitVectorTest.cpp @@ -11,14 +11,23 @@ #ifndef __ppc__ #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallBitVector.h" #include "gtest/gtest.h" using namespace llvm; namespace { -TEST(BitVectorTest, TrivialOperation) { - BitVector Vec; +// Test fixture +template <typename T> +class BitVectorTest : public ::testing::Test { }; + +// Test both BitVector and SmallBitVector with the same suite of tests. +typedef ::testing::Types<BitVector, SmallBitVector> BitVectorTestTypes; +TYPED_TEST_CASE(BitVectorTest, BitVectorTestTypes); + +TYPED_TEST(BitVectorTest, TrivialOperation) { + TypeParam Vec; EXPECT_EQ(0U, Vec.count()); EXPECT_EQ(0U, Vec.size()); EXPECT_FALSE(Vec.any()); @@ -42,7 +51,8 @@ TEST(BitVectorTest, TrivialOperation) { EXPECT_FALSE(Vec.none()); EXPECT_FALSE(Vec.empty()); - BitVector Inv = ~Vec; + TypeParam Inv = Vec; + Inv.flip(); EXPECT_EQ(6U, Inv.count()); EXPECT_EQ(11U, Inv.size()); EXPECT_TRUE(Inv.any()); @@ -52,7 +62,7 @@ TEST(BitVectorTest, TrivialOperation) { EXPECT_FALSE(Inv == Vec); EXPECT_TRUE(Inv != Vec); - Vec = ~Vec; + Vec.flip(); EXPECT_TRUE(Inv == Vec); EXPECT_FALSE(Inv != Vec); @@ -76,8 +86,8 @@ TEST(BitVectorTest, TrivialOperation) { EXPECT_FALSE(Vec[56]); Vec.resize(61, false); - BitVector Copy = Vec; - BitVector Alt(3, false); + TypeParam Copy = Vec; + TypeParam Alt(3, false); Alt.resize(6, true); std::swap(Alt, Vec); EXPECT_TRUE(Copy == Alt); @@ -131,7 +141,7 @@ TEST(BitVectorTest, TrivialOperation) { EXPECT_TRUE(Vec.none()); EXPECT_FALSE(Vec.empty()); - Inv = ~BitVector(); + Inv = TypeParam().flip(); EXPECT_EQ(0U, Inv.count()); EXPECT_EQ(0U, Inv.size()); EXPECT_FALSE(Inv.any()); @@ -148,13 +158,13 @@ TEST(BitVectorTest, TrivialOperation) { EXPECT_TRUE(Vec.empty()); } -TEST(BitVectorTest, CompoundAssignment) { - BitVector A; +TYPED_TEST(BitVectorTest, CompoundAssignment) { + TypeParam A; A.resize(10); A.set(4); A.set(7); - BitVector B; + TypeParam B; B.resize(50); B.set(5); B.set(18); @@ -187,8 +197,8 @@ TEST(BitVectorTest, CompoundAssignment) { EXPECT_EQ(100U, A.size()); } -TEST(BitVectorTest, ProxyIndex) { - BitVector Vec(3); +TYPED_TEST(BitVectorTest, ProxyIndex) { + TypeParam Vec(3); EXPECT_TRUE(Vec.none()); Vec[0] = Vec[1] = Vec[2] = true; EXPECT_EQ(Vec.size(), Vec.count()); @@ -196,8 +206,8 @@ TEST(BitVectorTest, ProxyIndex) { EXPECT_TRUE(Vec.none()); } -TEST(BitVectorTest, PortableBitMask) { - BitVector A; +TYPED_TEST(BitVectorTest, PortableBitMask) { + TypeParam A; const uint32_t Mask1[] = { 0x80000000, 6, 5 }; A.resize(10); @@ -242,6 +252,34 @@ TEST(BitVectorTest, PortableBitMask) { A.clearBitsNotInMask(Mask1, 1); EXPECT_EQ(64-4u, A.count()); } -} +TYPED_TEST(BitVectorTest, BinOps) { + TypeParam A; + TypeParam B; + + A.resize(65); + EXPECT_FALSE(A.anyCommon(B)); + EXPECT_FALSE(B.anyCommon(B)); + + B.resize(64); + A.set(64); + EXPECT_FALSE(A.anyCommon(B)); + EXPECT_FALSE(B.anyCommon(A)); + + B.set(63); + EXPECT_FALSE(A.anyCommon(B)); + EXPECT_FALSE(B.anyCommon(A)); + + A.set(63); + EXPECT_TRUE(A.anyCommon(B)); + EXPECT_TRUE(B.anyCommon(A)); + + B.resize(70); + B.set(64); + B.reset(63); + A.resize(64); + EXPECT_FALSE(A.anyCommon(B)); + EXPECT_FALSE(B.anyCommon(A)); +} +} #endif diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt new file mode 100644 index 0000000..d272b09 --- /dev/null +++ b/unittests/ADT/CMakeLists.txt @@ -0,0 +1,33 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_llvm_unittest(ADTTests + APFloatTest.cpp + APIntTest.cpp + BitVectorTest.cpp + DAGDeltaAlgorithmTest.cpp + DeltaAlgorithmTest.cpp + DenseMapTest.cpp + DenseSetTest.cpp + FoldingSet.cpp + HashingTest.cpp + ilistTest.cpp + ImmutableSetTest.cpp + IntEqClassesTest.cpp + IntervalMapTest.cpp + IntrusiveRefCntPtrTest.cpp + PackedVectorTest.cpp + SCCIteratorTest.cpp + SmallPtrSetTest.cpp + SmallStringTest.cpp + SmallVectorTest.cpp + SparseBitVectorTest.cpp + SparseSetTest.cpp + StringMapTest.cpp + StringRefTest.cpp + TinyPtrVectorTest.cpp + TripleTest.cpp + TwineTest.cpp + VariadicFunctionTest.cpp + ) diff --git a/unittests/ADT/DenseMapTest.cpp b/unittests/ADT/DenseMapTest.cpp index e0ee778..75e7006 100644 --- a/unittests/ADT/DenseMapTest.cpp +++ b/unittests/ADT/DenseMapTest.cpp @@ -9,170 +9,283 @@ #include "gtest/gtest.h" #include "llvm/ADT/DenseMap.h" +#include <map> +#include <set> using namespace llvm; namespace { -// Test fixture -class DenseMapTest : public testing::Test { -protected: - DenseMap<uint32_t, uint32_t> uintMap; - DenseMap<uint32_t *, uint32_t *> uintPtrMap; - uint32_t dummyInt; +uint32_t getTestKey(int i, uint32_t *) { return i; } +uint32_t getTestValue(int i, uint32_t *) { return 42 + i; } + +uint32_t *getTestKey(int i, uint32_t **) { + static uint32_t dummy_arr1[8192]; + assert(i < 8192 && "Only support 8192 dummy keys."); + return &dummy_arr1[i]; +} +uint32_t *getTestValue(int i, uint32_t **) { + static uint32_t dummy_arr1[8192]; + assert(i < 8192 && "Only support 8192 dummy keys."); + return &dummy_arr1[i]; +} + +/// \brief A test class that tries to check that construction and destruction +/// occur correctly. +class CtorTester { + static std::set<CtorTester *> Constructed; + int Value; + +public: + explicit CtorTester(int Value = 0) : Value(Value) { + EXPECT_TRUE(Constructed.insert(this).second); + } + CtorTester(uint32_t Value) : Value(Value) { + EXPECT_TRUE(Constructed.insert(this).second); + } + CtorTester(const CtorTester &Arg) : Value(Arg.Value) { + EXPECT_TRUE(Constructed.insert(this).second); + } + ~CtorTester() { + EXPECT_EQ(1u, Constructed.erase(this)); + } + operator uint32_t() const { return Value; } + + int getValue() const { return Value; } + bool operator==(const CtorTester &RHS) const { return Value == RHS.Value; } }; -// Empty map tests -TEST_F(DenseMapTest, EmptyIntMapTest) { - // Size tests - EXPECT_EQ(0u, uintMap.size()); - EXPECT_TRUE(uintMap.empty()); +std::set<CtorTester *> CtorTester::Constructed; - // Iterator tests - EXPECT_TRUE(uintMap.begin() == uintMap.end()); +struct CtorTesterMapInfo { + static inline CtorTester getEmptyKey() { return CtorTester(-1); } + static inline CtorTester getTombstoneKey() { return CtorTester(-2); } + static unsigned getHashValue(const CtorTester &Val) { + return Val.getValue() * 37u; + } + static bool isEqual(const CtorTester &LHS, const CtorTester &RHS) { + return LHS == RHS; + } +}; - // Lookup tests - EXPECT_FALSE(uintMap.count(0u)); - EXPECT_TRUE(uintMap.find(0u) == uintMap.end()); - EXPECT_EQ(0u, uintMap.lookup(0u)); -} +CtorTester getTestKey(int i, CtorTester *) { return CtorTester(i); } +CtorTester getTestValue(int i, CtorTester *) { return CtorTester(42 + i); } + +// Test fixture, with helper functions implemented by forwarding to global +// function overloads selected by component types of the type parameter. This +// allows all of the map implementations to be tested with shared +// implementations of helper routines. +template <typename T> +class DenseMapTest : public ::testing::Test { +protected: + T Map; + + static typename T::key_type *const dummy_key_ptr; + static typename T::mapped_type *const dummy_value_ptr; + + typename T::key_type getKey(int i = 0) { + return getTestKey(i, dummy_key_ptr); + } + typename T::mapped_type getValue(int i = 0) { + return getTestValue(i, dummy_value_ptr); + } +}; -// Empty map tests for pointer map -TEST_F(DenseMapTest, EmptyPtrMapTest) { +template <typename T> +typename T::key_type *const DenseMapTest<T>::dummy_key_ptr = 0; +template <typename T> +typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = 0; + +// Register these types for testing. +typedef ::testing::Types<DenseMap<uint32_t, uint32_t>, + DenseMap<uint32_t *, uint32_t *>, + DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>, + SmallDenseMap<uint32_t, uint32_t>, + SmallDenseMap<uint32_t *, uint32_t *>, + SmallDenseMap<CtorTester, CtorTester, 4, + CtorTesterMapInfo> + > DenseMapTestTypes; +TYPED_TEST_CASE(DenseMapTest, DenseMapTestTypes); + +// Empty map tests +TYPED_TEST(DenseMapTest, EmptyIntMapTest) { // Size tests - EXPECT_EQ(0u, uintPtrMap.size()); - EXPECT_TRUE(uintPtrMap.empty()); + EXPECT_EQ(0u, this->Map.size()); + EXPECT_TRUE(this->Map.empty()); // Iterator tests - EXPECT_TRUE(uintPtrMap.begin() == uintPtrMap.end()); + EXPECT_TRUE(this->Map.begin() == this->Map.end()); // Lookup tests - EXPECT_FALSE(uintPtrMap.count(&dummyInt)); - EXPECT_TRUE(uintPtrMap.find(&dummyInt) == uintPtrMap.begin()); - EXPECT_EQ(0, uintPtrMap.lookup(&dummyInt)); + EXPECT_FALSE(this->Map.count(this->getKey())); + EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end()); +#ifndef _MSC_VER + EXPECT_EQ(typename TypeParam::mapped_type(), + this->Map.lookup(this->getKey())); +#else + // MSVC, at least old versions, cannot parse the typename to disambiguate + // TypeParam::mapped_type as a type. However, because MSVC doesn't implement + // two-phase name lookup, it also doesn't require the typename. Deal with + // this mutual incompatibility through specialized code. + EXPECT_EQ(TypeParam::mapped_type(), + this->Map.lookup(this->getKey())); +#endif } // Constant map tests -TEST_F(DenseMapTest, ConstEmptyMapTest) { - const DenseMap<uint32_t, uint32_t> & constUintMap = uintMap; - const DenseMap<uint32_t *, uint32_t *> & constUintPtrMap = uintPtrMap; - EXPECT_EQ(0u, constUintMap.size()); - EXPECT_EQ(0u, constUintPtrMap.size()); - EXPECT_TRUE(constUintMap.empty()); - EXPECT_TRUE(constUintPtrMap.empty()); - EXPECT_TRUE(constUintMap.begin() == constUintMap.end()); - EXPECT_TRUE(constUintPtrMap.begin() == constUintPtrMap.end()); +TYPED_TEST(DenseMapTest, ConstEmptyMapTest) { + const TypeParam &ConstMap = this->Map; + EXPECT_EQ(0u, ConstMap.size()); + EXPECT_TRUE(ConstMap.empty()); + EXPECT_TRUE(ConstMap.begin() == ConstMap.end()); } // A map with a single entry -TEST_F(DenseMapTest, SingleEntryMapTest) { - uintMap[0] = 1; +TYPED_TEST(DenseMapTest, SingleEntryMapTest) { + this->Map[this->getKey()] = this->getValue(); // Size tests - EXPECT_EQ(1u, uintMap.size()); - EXPECT_FALSE(uintMap.begin() == uintMap.end()); - EXPECT_FALSE(uintMap.empty()); + EXPECT_EQ(1u, this->Map.size()); + EXPECT_FALSE(this->Map.begin() == this->Map.end()); + EXPECT_FALSE(this->Map.empty()); // Iterator tests - DenseMap<uint32_t, uint32_t>::iterator it = uintMap.begin(); - EXPECT_EQ(0u, it->first); - EXPECT_EQ(1u, it->second); + typename TypeParam::iterator it = this->Map.begin(); + EXPECT_EQ(this->getKey(), it->first); + EXPECT_EQ(this->getValue(), it->second); ++it; - EXPECT_TRUE(it == uintMap.end()); + EXPECT_TRUE(it == this->Map.end()); // Lookup tests - EXPECT_TRUE(uintMap.count(0u)); - EXPECT_TRUE(uintMap.find(0u) == uintMap.begin()); - EXPECT_EQ(1u, uintMap.lookup(0u)); - EXPECT_EQ(1u, uintMap[0]); + EXPECT_TRUE(this->Map.count(this->getKey())); + EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.begin()); + EXPECT_EQ(this->getValue(), this->Map.lookup(this->getKey())); + EXPECT_EQ(this->getValue(), this->Map[this->getKey()]); } // Test clear() method -TEST_F(DenseMapTest, ClearTest) { - uintMap[0] = 1; - uintMap.clear(); +TYPED_TEST(DenseMapTest, ClearTest) { + this->Map[this->getKey()] = this->getValue(); + this->Map.clear(); - EXPECT_EQ(0u, uintMap.size()); - EXPECT_TRUE(uintMap.empty()); - EXPECT_TRUE(uintMap.begin() == uintMap.end()); + EXPECT_EQ(0u, this->Map.size()); + EXPECT_TRUE(this->Map.empty()); + EXPECT_TRUE(this->Map.begin() == this->Map.end()); } // Test erase(iterator) method -TEST_F(DenseMapTest, EraseTest) { - uintMap[0] = 1; - uintMap.erase(uintMap.begin()); +TYPED_TEST(DenseMapTest, EraseTest) { + this->Map[this->getKey()] = this->getValue(); + this->Map.erase(this->Map.begin()); - EXPECT_EQ(0u, uintMap.size()); - EXPECT_TRUE(uintMap.empty()); - EXPECT_TRUE(uintMap.begin() == uintMap.end()); + EXPECT_EQ(0u, this->Map.size()); + EXPECT_TRUE(this->Map.empty()); + EXPECT_TRUE(this->Map.begin() == this->Map.end()); } // Test erase(value) method -TEST_F(DenseMapTest, EraseTest2) { - uintMap[0] = 1; - uintMap.erase(0); +TYPED_TEST(DenseMapTest, EraseTest2) { + this->Map[this->getKey()] = this->getValue(); + this->Map.erase(this->getKey()); - EXPECT_EQ(0u, uintMap.size()); - EXPECT_TRUE(uintMap.empty()); - EXPECT_TRUE(uintMap.begin() == uintMap.end()); + EXPECT_EQ(0u, this->Map.size()); + EXPECT_TRUE(this->Map.empty()); + EXPECT_TRUE(this->Map.begin() == this->Map.end()); } // Test insert() method -TEST_F(DenseMapTest, InsertTest) { - uintMap.insert(std::make_pair(0u, 1u)); - EXPECT_EQ(1u, uintMap.size()); - EXPECT_EQ(1u, uintMap[0]); +TYPED_TEST(DenseMapTest, InsertTest) { + this->Map.insert(std::make_pair(this->getKey(), this->getValue())); + EXPECT_EQ(1u, this->Map.size()); + EXPECT_EQ(this->getValue(), this->Map[this->getKey()]); } // Test copy constructor method -TEST_F(DenseMapTest, CopyConstructorTest) { - uintMap[0] = 1; - DenseMap<uint32_t, uint32_t> copyMap(uintMap); +TYPED_TEST(DenseMapTest, CopyConstructorTest) { + this->Map[this->getKey()] = this->getValue(); + TypeParam copyMap(this->Map); EXPECT_EQ(1u, copyMap.size()); - EXPECT_EQ(1u, copyMap[0]); + EXPECT_EQ(this->getValue(), copyMap[this->getKey()]); } // Test assignment operator method -TEST_F(DenseMapTest, AssignmentTest) { - uintMap[0] = 1; - DenseMap<uint32_t, uint32_t> copyMap = uintMap; +TYPED_TEST(DenseMapTest, AssignmentTest) { + this->Map[this->getKey()] = this->getValue(); + TypeParam copyMap = this->Map; EXPECT_EQ(1u, copyMap.size()); - EXPECT_EQ(1u, copyMap[0]); + EXPECT_EQ(this->getValue(), copyMap[this->getKey()]); +} + +// Test swap method +TYPED_TEST(DenseMapTest, SwapTest) { + this->Map[this->getKey()] = this->getValue(); + TypeParam otherMap; + + this->Map.swap(otherMap); + EXPECT_EQ(0u, this->Map.size()); + EXPECT_TRUE(this->Map.empty()); + EXPECT_EQ(1u, otherMap.size()); + EXPECT_EQ(this->getValue(), otherMap[this->getKey()]); + + this->Map.swap(otherMap); + EXPECT_EQ(0u, otherMap.size()); + EXPECT_TRUE(otherMap.empty()); + EXPECT_EQ(1u, this->Map.size()); + EXPECT_EQ(this->getValue(), this->Map[this->getKey()]); + + // Make this more interesting by inserting 100 numbers into the map. + for (int i = 0; i < 100; ++i) + this->Map[this->getKey(i)] = this->getValue(i); + + this->Map.swap(otherMap); + EXPECT_EQ(0u, this->Map.size()); + EXPECT_TRUE(this->Map.empty()); + EXPECT_EQ(100u, otherMap.size()); + for (int i = 0; i < 100; ++i) + EXPECT_EQ(this->getValue(i), otherMap[this->getKey(i)]); + + this->Map.swap(otherMap); + EXPECT_EQ(0u, otherMap.size()); + EXPECT_TRUE(otherMap.empty()); + EXPECT_EQ(100u, this->Map.size()); + for (int i = 0; i < 100; ++i) + EXPECT_EQ(this->getValue(i), this->Map[this->getKey(i)]); } // A more complex iteration test -TEST_F(DenseMapTest, IterationTest) { +TYPED_TEST(DenseMapTest, IterationTest) { bool visited[100]; + std::map<typename TypeParam::key_type, unsigned> visitedIndex; // Insert 100 numbers into the map for (int i = 0; i < 100; ++i) { visited[i] = false; - uintMap[i] = 3; + visitedIndex[this->getKey(i)] = i; + + this->Map[this->getKey(i)] = this->getValue(i); } // Iterate over all numbers and mark each one found. - for (DenseMap<uint32_t, uint32_t>::iterator it = uintMap.begin(); - it != uintMap.end(); ++it) { - visited[it->first] = true; - } + for (typename TypeParam::iterator it = this->Map.begin(); + it != this->Map.end(); ++it) + visited[visitedIndex[it->first]] = true; // Ensure every number was visited. - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 100; ++i) ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited"; - } } // const_iterator test -TEST_F(DenseMapTest, ConstIteratorTest) { +TYPED_TEST(DenseMapTest, ConstIteratorTest) { // Check conversion from iterator to const_iterator. - DenseMap<uint32_t, uint32_t>::iterator it = uintMap.begin(); - DenseMap<uint32_t, uint32_t>::const_iterator cit(it); + typename TypeParam::iterator it = this->Map.begin(); + typename TypeParam::const_iterator cit(it); EXPECT_TRUE(it == cit); // Check copying of const_iterators. - DenseMap<uint32_t, uint32_t>::const_iterator cit2(cit); + typename TypeParam::const_iterator cit2(cit); EXPECT_TRUE(cit == cit2); } @@ -194,7 +307,7 @@ struct TestDenseMapInfo { }; // find_as() tests -TEST_F(DenseMapTest, FindAsTest) { +TEST(DenseMapCustomTest, FindAsTest) { DenseMap<unsigned, unsigned, TestDenseMapInfo> map; map[0] = 1; map[1] = 2; diff --git a/unittests/ADT/HashingTest.cpp b/unittests/ADT/HashingTest.cpp index b148f14..1b3d061 100644 --- a/unittests/ADT/HashingTest.cpp +++ b/unittests/ADT/HashingTest.cpp @@ -345,7 +345,7 @@ TEST(HashingTest, HashCombineBasicTest) { EXPECT_EQ(hash_combine_range(arr1, arr1 + 6), hash_combine(i1, i2, i3, i4, i5, i6)); - // Hashing a sequence of heterogenous types which *happen* to all produce the + // Hashing a sequence of heterogeneous types which *happen* to all produce the // same data for hashing produces the same as a range-based hash of the // fundamental values. const size_t s1 = 1024, s2 = 8888, s3 = 9000000; diff --git a/unittests/ADT/SmallBitVectorTest.cpp b/unittests/ADT/SmallBitVectorTest.cpp deleted file mode 100644 index c4dda9e..0000000 --- a/unittests/ADT/SmallBitVectorTest.cpp +++ /dev/null @@ -1,196 +0,0 @@ -//===- llvm/unittest/ADT/SmallBitVectorTest.cpp - SmallBitVector tests ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/SmallBitVector.h" -#include "gtest/gtest.h" - -using namespace llvm; - -namespace { - -TEST(SmallBitVectorTest, TrivialOperation) { - SmallBitVector Vec; - EXPECT_EQ(0U, Vec.count()); - EXPECT_EQ(0U, Vec.size()); - EXPECT_FALSE(Vec.any()); - EXPECT_TRUE(Vec.all()); - EXPECT_TRUE(Vec.none()); - EXPECT_TRUE(Vec.empty()); - - Vec.resize(5, true); - EXPECT_EQ(5U, Vec.count()); - EXPECT_EQ(5U, Vec.size()); - EXPECT_TRUE(Vec.any()); - EXPECT_TRUE(Vec.all()); - EXPECT_FALSE(Vec.none()); - EXPECT_FALSE(Vec.empty()); - - Vec.resize(11); - EXPECT_EQ(5U, Vec.count()); - EXPECT_EQ(11U, Vec.size()); - EXPECT_TRUE(Vec.any()); - EXPECT_FALSE(Vec.all()); - EXPECT_FALSE(Vec.none()); - EXPECT_FALSE(Vec.empty()); - - SmallBitVector Inv = ~Vec; - EXPECT_EQ(6U, Inv.count()); - EXPECT_EQ(11U, Inv.size()); - EXPECT_TRUE(Inv.any()); - EXPECT_FALSE(Inv.all()); - EXPECT_FALSE(Inv.none()); - EXPECT_FALSE(Inv.empty()); - - EXPECT_FALSE(Inv == Vec); - EXPECT_TRUE(Inv != Vec); - Vec = ~Vec; - EXPECT_TRUE(Inv == Vec); - EXPECT_FALSE(Inv != Vec); - - // Add some "interesting" data to Vec. - Vec.resize(23, true); - Vec.resize(25, false); - Vec.resize(26, true); - Vec.resize(29, false); - Vec.resize(33, true); - Vec.resize(57, false); - unsigned Count = 0; - for (unsigned i = Vec.find_first(); i != -1u; i = Vec.find_next(i)) { - ++Count; - EXPECT_TRUE(Vec[i]); - EXPECT_TRUE(Vec.test(i)); - } - EXPECT_EQ(Count, Vec.count()); - EXPECT_EQ(Count, 23u); - EXPECT_FALSE(Vec[0]); - EXPECT_TRUE(Vec[32]); - EXPECT_FALSE(Vec[56]); - Vec.resize(61, false); - - SmallBitVector Copy = Vec; - SmallBitVector Alt(3, false); - Alt.resize(6, true); - std::swap(Alt, Vec); - EXPECT_TRUE(Copy == Alt); - EXPECT_TRUE(Vec.size() == 6); - EXPECT_TRUE(Vec.count() == 3); - EXPECT_TRUE(Vec.find_first() == 3); - std::swap(Copy, Vec); - - // Add some more "interesting" data. - Vec.resize(68, true); - Vec.resize(78, false); - Vec.resize(89, true); - Vec.resize(90, false); - Vec.resize(91, true); - Vec.resize(130, false); - Count = 0; - for (unsigned i = Vec.find_first(); i != -1u; i = Vec.find_next(i)) { - ++Count; - EXPECT_TRUE(Vec[i]); - EXPECT_TRUE(Vec.test(i)); - } - EXPECT_EQ(Count, Vec.count()); - EXPECT_EQ(Count, 42u); - EXPECT_FALSE(Vec[0]); - EXPECT_TRUE(Vec[32]); - EXPECT_FALSE(Vec[60]); - EXPECT_FALSE(Vec[129]); - - Vec.flip(60); - EXPECT_TRUE(Vec[60]); - EXPECT_EQ(Count + 1, Vec.count()); - Vec.flip(60); - EXPECT_FALSE(Vec[60]); - EXPECT_EQ(Count, Vec.count()); - - Vec.reset(32); - EXPECT_FALSE(Vec[32]); - EXPECT_EQ(Count - 1, Vec.count()); - Vec.set(32); - EXPECT_TRUE(Vec[32]); - EXPECT_EQ(Count, Vec.count()); - - Vec.flip(); - EXPECT_EQ(Vec.size() - Count, Vec.count()); - - Vec.reset(); - EXPECT_EQ(0U, Vec.count()); - EXPECT_EQ(130U, Vec.size()); - EXPECT_FALSE(Vec.any()); - EXPECT_FALSE(Vec.all()); - EXPECT_TRUE(Vec.none()); - EXPECT_FALSE(Vec.empty()); - - Inv = ~SmallBitVector(); - EXPECT_EQ(0U, Inv.count()); - EXPECT_EQ(0U, Inv.size()); - EXPECT_FALSE(Inv.any()); - EXPECT_TRUE(Inv.all()); - EXPECT_TRUE(Inv.none()); - EXPECT_TRUE(Inv.empty()); - - Vec.clear(); - EXPECT_EQ(0U, Vec.count()); - EXPECT_EQ(0U, Vec.size()); - EXPECT_FALSE(Vec.any()); - EXPECT_TRUE(Vec.all()); - EXPECT_TRUE(Vec.none()); - EXPECT_TRUE(Vec.empty()); -} - -TEST(SmallBitVectorTest, CompoundAssignment) { - SmallBitVector A; - A.resize(10); - A.set(4); - A.set(7); - - SmallBitVector B; - B.resize(50); - B.set(5); - B.set(18); - - A |= B; - EXPECT_TRUE(A.test(4)); - EXPECT_TRUE(A.test(5)); - EXPECT_TRUE(A.test(7)); - EXPECT_TRUE(A.test(18)); - EXPECT_EQ(4U, A.count()); - EXPECT_EQ(50U, A.size()); - - B.resize(10); - B.set(); - B.reset(2); - B.reset(7); - A &= B; - EXPECT_FALSE(A.test(2)); - EXPECT_FALSE(A.test(7)); - EXPECT_EQ(2U, A.count()); - EXPECT_EQ(50U, A.size()); - - B.resize(100); - B.set(); - - A ^= B; - EXPECT_TRUE(A.test(2)); - EXPECT_TRUE(A.test(7)); - EXPECT_EQ(98U, A.count()); - EXPECT_EQ(100U, A.size()); -} - -TEST(SmallBitVectorTest, ProxyIndex) { - SmallBitVector Vec(3); - EXPECT_TRUE(Vec.none()); - Vec[0] = Vec[1] = Vec[2] = true; - EXPECT_EQ(Vec.size(), Vec.count()); - Vec[2] = Vec[1] = Vec[0] = false; - EXPECT_TRUE(Vec.none()); -} - -} diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index d5bfe76..7fd71f5 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -88,18 +88,17 @@ int Constructable::numDestructorCalls; int Constructable::numAssignmentCalls; // Test fixture class +template <typename VectorT> class SmallVectorTest : public testing::Test { protected: - typedef SmallVector<Constructable, 4> VectorType; - - VectorType theVector; - VectorType otherVector; + VectorT theVector; + VectorT otherVector; void SetUp() { Constructable::reset(); } - void assertEmpty(VectorType & v) { + void assertEmpty(VectorT & v) { // Size tests EXPECT_EQ(0u, v.size()); EXPECT_TRUE(v.empty()); @@ -109,7 +108,7 @@ protected: } // Assert that theVector contains the specified values, in order. - void assertValuesInOrder(VectorType & v, size_t size, ...) { + void assertValuesInOrder(VectorT & v, size_t size, ...) { EXPECT_EQ(size, v.size()); va_list ap; @@ -123,267 +122,327 @@ protected: } // Generate a sequence of values to initialize the vector. - void makeSequence(VectorType & v, int start, int end) { + void makeSequence(VectorT & v, int start, int end) { for (int i = start; i <= end; ++i) { v.push_back(Constructable(i)); } } }; +typedef ::testing::Types<SmallVector<Constructable, 0>, + SmallVector<Constructable, 1>, + SmallVector<Constructable, 2>, + SmallVector<Constructable, 4> + > SmallVectorTestTypes; +TYPED_TEST_CASE(SmallVectorTest, SmallVectorTestTypes); + // New vector test. -TEST_F(SmallVectorTest, EmptyVectorTest) { +TYPED_TEST(SmallVectorTest, EmptyVectorTest) { SCOPED_TRACE("EmptyVectorTest"); - assertEmpty(theVector); - EXPECT_TRUE(theVector.rbegin() == theVector.rend()); + this->assertEmpty(this->theVector); + EXPECT_TRUE(this->theVector.rbegin() == this->theVector.rend()); EXPECT_EQ(0, Constructable::getNumConstructorCalls()); EXPECT_EQ(0, Constructable::getNumDestructorCalls()); } // Simple insertions and deletions. -TEST_F(SmallVectorTest, PushPopTest) { +TYPED_TEST(SmallVectorTest, PushPopTest) { SCOPED_TRACE("PushPopTest"); + // Track whether the vector will potentially have to grow. + bool RequiresGrowth = this->theVector.capacity() < 3; + // Push an element - theVector.push_back(Constructable(1)); + this->theVector.push_back(Constructable(1)); // Size tests - assertValuesInOrder(theVector, 1u, 1); - EXPECT_FALSE(theVector.begin() == theVector.end()); - EXPECT_FALSE(theVector.empty()); + this->assertValuesInOrder(this->theVector, 1u, 1); + EXPECT_FALSE(this->theVector.begin() == this->theVector.end()); + EXPECT_FALSE(this->theVector.empty()); // Push another element - theVector.push_back(Constructable(2)); - assertValuesInOrder(theVector, 2u, 1, 2); + this->theVector.push_back(Constructable(2)); + this->assertValuesInOrder(this->theVector, 2u, 1, 2); // Insert at beginning - theVector.insert(theVector.begin(), theVector[1]); - assertValuesInOrder(theVector, 3u, 2, 1, 2); + this->theVector.insert(this->theVector.begin(), this->theVector[1]); + this->assertValuesInOrder(this->theVector, 3u, 2, 1, 2); // Pop one element - theVector.pop_back(); - assertValuesInOrder(theVector, 2u, 2, 1); + this->theVector.pop_back(); + this->assertValuesInOrder(this->theVector, 2u, 2, 1); // Pop remaining elements - theVector.pop_back(); - theVector.pop_back(); - assertEmpty(theVector); + this->theVector.pop_back(); + this->theVector.pop_back(); + this->assertEmpty(this->theVector); // Check number of constructor calls. Should be 2 for each list element, // one for the argument to push_back, one for the argument to insert, // and one for the list element itself. - EXPECT_EQ(5, Constructable::getNumConstructorCalls()); - EXPECT_EQ(5, Constructable::getNumDestructorCalls()); + if (!RequiresGrowth) { + EXPECT_EQ(5, Constructable::getNumConstructorCalls()); + EXPECT_EQ(5, Constructable::getNumDestructorCalls()); + } else { + // If we had to grow the vector, these only have a lower bound, but should + // always be equal. + EXPECT_LE(5, Constructable::getNumConstructorCalls()); + EXPECT_EQ(Constructable::getNumConstructorCalls(), + Constructable::getNumDestructorCalls()); + } } // Clear test. -TEST_F(SmallVectorTest, ClearTest) { +TYPED_TEST(SmallVectorTest, ClearTest) { SCOPED_TRACE("ClearTest"); - makeSequence(theVector, 1, 2); - theVector.clear(); + this->theVector.reserve(2); + this->makeSequence(this->theVector, 1, 2); + this->theVector.clear(); - assertEmpty(theVector); + this->assertEmpty(this->theVector); EXPECT_EQ(4, Constructable::getNumConstructorCalls()); EXPECT_EQ(4, Constructable::getNumDestructorCalls()); } // Resize smaller test. -TEST_F(SmallVectorTest, ResizeShrinkTest) { +TYPED_TEST(SmallVectorTest, ResizeShrinkTest) { SCOPED_TRACE("ResizeShrinkTest"); - makeSequence(theVector, 1, 3); - theVector.resize(1); + this->theVector.reserve(3); + this->makeSequence(this->theVector, 1, 3); + this->theVector.resize(1); - assertValuesInOrder(theVector, 1u, 1); + this->assertValuesInOrder(this->theVector, 1u, 1); EXPECT_EQ(6, Constructable::getNumConstructorCalls()); EXPECT_EQ(5, Constructable::getNumDestructorCalls()); } // Resize bigger test. -TEST_F(SmallVectorTest, ResizeGrowTest) { +TYPED_TEST(SmallVectorTest, ResizeGrowTest) { SCOPED_TRACE("ResizeGrowTest"); - theVector.resize(2); + this->theVector.resize(2); // The extra constructor/destructor calls come from the temporary object used // to initialize the contents of the resized array (via copy construction). EXPECT_EQ(3, Constructable::getNumConstructorCalls()); EXPECT_EQ(1, Constructable::getNumDestructorCalls()); - EXPECT_EQ(2u, theVector.size()); + EXPECT_EQ(2u, this->theVector.size()); } // Resize with fill value. -TEST_F(SmallVectorTest, ResizeFillTest) { +TYPED_TEST(SmallVectorTest, ResizeFillTest) { SCOPED_TRACE("ResizeFillTest"); - theVector.resize(3, Constructable(77)); - assertValuesInOrder(theVector, 3u, 77, 77, 77); + this->theVector.resize(3, Constructable(77)); + this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77); } // Overflow past fixed size. -TEST_F(SmallVectorTest, OverflowTest) { +TYPED_TEST(SmallVectorTest, OverflowTest) { SCOPED_TRACE("OverflowTest"); // Push more elements than the fixed size. - makeSequence(theVector, 1, 10); + this->makeSequence(this->theVector, 1, 10); // Test size and values. - EXPECT_EQ(10u, theVector.size()); + EXPECT_EQ(10u, this->theVector.size()); for (int i = 0; i < 10; ++i) { - EXPECT_EQ(i+1, theVector[i].getValue()); + EXPECT_EQ(i+1, this->theVector[i].getValue()); } // Now resize back to fixed size. - theVector.resize(1); + this->theVector.resize(1); - assertValuesInOrder(theVector, 1u, 1); + this->assertValuesInOrder(this->theVector, 1u, 1); } // Iteration tests. -TEST_F(SmallVectorTest, IterationTest) { - makeSequence(theVector, 1, 2); +TYPED_TEST(SmallVectorTest, IterationTest) { + this->makeSequence(this->theVector, 1, 2); // Forward Iteration - VectorType::iterator it = theVector.begin(); - EXPECT_TRUE(*it == theVector.front()); - EXPECT_TRUE(*it == theVector[0]); + typename TypeParam::iterator it = this->theVector.begin(); + EXPECT_TRUE(*it == this->theVector.front()); + EXPECT_TRUE(*it == this->theVector[0]); EXPECT_EQ(1, it->getValue()); ++it; - EXPECT_TRUE(*it == theVector[1]); - EXPECT_TRUE(*it == theVector.back()); + EXPECT_TRUE(*it == this->theVector[1]); + EXPECT_TRUE(*it == this->theVector.back()); EXPECT_EQ(2, it->getValue()); ++it; - EXPECT_TRUE(it == theVector.end()); + EXPECT_TRUE(it == this->theVector.end()); --it; - EXPECT_TRUE(*it == theVector[1]); + EXPECT_TRUE(*it == this->theVector[1]); EXPECT_EQ(2, it->getValue()); --it; - EXPECT_TRUE(*it == theVector[0]); + EXPECT_TRUE(*it == this->theVector[0]); EXPECT_EQ(1, it->getValue()); // Reverse Iteration - VectorType::reverse_iterator rit = theVector.rbegin(); - EXPECT_TRUE(*rit == theVector[1]); + typename TypeParam::reverse_iterator rit = this->theVector.rbegin(); + EXPECT_TRUE(*rit == this->theVector[1]); EXPECT_EQ(2, rit->getValue()); ++rit; - EXPECT_TRUE(*rit == theVector[0]); + EXPECT_TRUE(*rit == this->theVector[0]); EXPECT_EQ(1, rit->getValue()); ++rit; - EXPECT_TRUE(rit == theVector.rend()); + EXPECT_TRUE(rit == this->theVector.rend()); --rit; - EXPECT_TRUE(*rit == theVector[0]); + EXPECT_TRUE(*rit == this->theVector[0]); EXPECT_EQ(1, rit->getValue()); --rit; - EXPECT_TRUE(*rit == theVector[1]); + EXPECT_TRUE(*rit == this->theVector[1]); EXPECT_EQ(2, rit->getValue()); } // Swap test. -TEST_F(SmallVectorTest, SwapTest) { +TYPED_TEST(SmallVectorTest, SwapTest) { SCOPED_TRACE("SwapTest"); - makeSequence(theVector, 1, 2); - std::swap(theVector, otherVector); + this->makeSequence(this->theVector, 1, 2); + std::swap(this->theVector, this->otherVector); - assertEmpty(theVector); - assertValuesInOrder(otherVector, 2u, 1, 2); + this->assertEmpty(this->theVector); + this->assertValuesInOrder(this->otherVector, 2u, 1, 2); } // Append test -TEST_F(SmallVectorTest, AppendTest) { +TYPED_TEST(SmallVectorTest, AppendTest) { SCOPED_TRACE("AppendTest"); - makeSequence(otherVector, 2, 3); + this->makeSequence(this->otherVector, 2, 3); - theVector.push_back(Constructable(1)); - theVector.append(otherVector.begin(), otherVector.end()); + this->theVector.push_back(Constructable(1)); + this->theVector.append(this->otherVector.begin(), this->otherVector.end()); - assertValuesInOrder(theVector, 3u, 1, 2, 3); + this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); } // Append repeated test -TEST_F(SmallVectorTest, AppendRepeatedTest) { +TYPED_TEST(SmallVectorTest, AppendRepeatedTest) { SCOPED_TRACE("AppendRepeatedTest"); - theVector.push_back(Constructable(1)); - theVector.append(2, Constructable(77)); - assertValuesInOrder(theVector, 3u, 1, 77, 77); + this->theVector.push_back(Constructable(1)); + this->theVector.append(2, Constructable(77)); + this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77); } // Assign test -TEST_F(SmallVectorTest, AssignTest) { +TYPED_TEST(SmallVectorTest, AssignTest) { SCOPED_TRACE("AssignTest"); - theVector.push_back(Constructable(1)); - theVector.assign(2, Constructable(77)); - assertValuesInOrder(theVector, 2u, 77, 77); + this->theVector.push_back(Constructable(1)); + this->theVector.assign(2, Constructable(77)); + this->assertValuesInOrder(this->theVector, 2u, 77, 77); } // Erase a single element -TEST_F(SmallVectorTest, EraseTest) { +TYPED_TEST(SmallVectorTest, EraseTest) { SCOPED_TRACE("EraseTest"); - makeSequence(theVector, 1, 3); - theVector.erase(theVector.begin()); - assertValuesInOrder(theVector, 2u, 2, 3); + this->makeSequence(this->theVector, 1, 3); + this->theVector.erase(this->theVector.begin()); + this->assertValuesInOrder(this->theVector, 2u, 2, 3); } // Erase a range of elements -TEST_F(SmallVectorTest, EraseRangeTest) { +TYPED_TEST(SmallVectorTest, EraseRangeTest) { SCOPED_TRACE("EraseRangeTest"); - makeSequence(theVector, 1, 3); - theVector.erase(theVector.begin(), theVector.begin() + 2); - assertValuesInOrder(theVector, 1u, 3); + this->makeSequence(this->theVector, 1, 3); + this->theVector.erase(this->theVector.begin(), this->theVector.begin() + 2); + this->assertValuesInOrder(this->theVector, 1u, 3); } // Insert a single element. -TEST_F(SmallVectorTest, InsertTest) { +TYPED_TEST(SmallVectorTest, InsertTest) { SCOPED_TRACE("InsertTest"); - makeSequence(theVector, 1, 3); - theVector.insert(theVector.begin() + 1, Constructable(77)); - assertValuesInOrder(theVector, 4u, 1, 77, 2, 3); + this->makeSequence(this->theVector, 1, 3); + typename TypeParam::iterator I = + this->theVector.insert(this->theVector.begin() + 1, Constructable(77)); + EXPECT_EQ(this->theVector.begin() + 1, I); + this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3); } // Insert repeated elements. -TEST_F(SmallVectorTest, InsertRepeatedTest) { +TYPED_TEST(SmallVectorTest, InsertRepeatedTest) { SCOPED_TRACE("InsertRepeatedTest"); - makeSequence(theVector, 10, 15); - theVector.insert(theVector.begin() + 1, 2, Constructable(16)); - assertValuesInOrder(theVector, 8u, 10, 16, 16, 11, 12, 13, 14, 15); + this->makeSequence(this->theVector, 10, 15); + typename TypeParam::iterator I = + this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16)); + EXPECT_EQ(this->theVector.begin() + 1, I); + this->assertValuesInOrder(this->theVector, 8u, + 10, 16, 16, 11, 12, 13, 14, 15); + + // Insert at end. + I = this->theVector.insert(this->theVector.end(), 2, Constructable(16)); + EXPECT_EQ(this->theVector.begin() + 8, I); + this->assertValuesInOrder(this->theVector, 10u, + 10, 16, 16, 11, 12, 13, 14, 15, 16, 16); + + // Empty insert. + EXPECT_EQ(this->theVector.end(), + this->theVector.insert(this->theVector.end(), + 0, Constructable(42))); + EXPECT_EQ(this->theVector.begin() + 1, + this->theVector.insert(this->theVector.begin() + 1, + 0, Constructable(42))); } // Insert range. -TEST_F(SmallVectorTest, InsertRangeTest) { - SCOPED_TRACE("InsertRepeatedTest"); - - makeSequence(theVector, 1, 3); - theVector.insert(theVector.begin() + 1, 3, Constructable(77)); - assertValuesInOrder(theVector, 6u, 1, 77, 77, 77, 2, 3); +TYPED_TEST(SmallVectorTest, InsertRangeTest) { + SCOPED_TRACE("InsertRangeTest"); + + Constructable Arr[3] = + { Constructable(77), Constructable(77), Constructable(77) }; + + this->makeSequence(this->theVector, 1, 3); + typename TypeParam::iterator I = + this->theVector.insert(this->theVector.begin() + 1, Arr, Arr+3); + EXPECT_EQ(this->theVector.begin() + 1, I); + this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3); + + // Insert at end. + I = this->theVector.insert(this->theVector.end(), Arr, Arr+3); + EXPECT_EQ(this->theVector.begin() + 6, I); + this->assertValuesInOrder(this->theVector, 9u, + 1, 77, 77, 77, 2, 3, 77, 77, 77); + + // Empty insert. + EXPECT_EQ(this->theVector.end(), + this->theVector.insert(this->theVector.end(), + this->theVector.begin(), + this->theVector.begin())); + EXPECT_EQ(this->theVector.begin() + 1, + this->theVector.insert(this->theVector.begin() + 1, + this->theVector.begin(), + this->theVector.begin())); } // Comparison tests. -TEST_F(SmallVectorTest, ComparisonTest) { +TYPED_TEST(SmallVectorTest, ComparisonTest) { SCOPED_TRACE("ComparisonTest"); - makeSequence(theVector, 1, 3); - makeSequence(otherVector, 1, 3); + this->makeSequence(this->theVector, 1, 3); + this->makeSequence(this->otherVector, 1, 3); - EXPECT_TRUE(theVector == otherVector); - EXPECT_FALSE(theVector != otherVector); + EXPECT_TRUE(this->theVector == this->otherVector); + EXPECT_FALSE(this->theVector != this->otherVector); - otherVector.clear(); - makeSequence(otherVector, 2, 4); + this->otherVector.clear(); + this->makeSequence(this->otherVector, 2, 4); - EXPECT_FALSE(theVector == otherVector); - EXPECT_TRUE(theVector != otherVector); + EXPECT_FALSE(this->theVector == this->otherVector); + EXPECT_TRUE(this->theVector != this->otherVector); } // Constant vector tests. -TEST_F(SmallVectorTest, ConstVectorTest) { - VectorType constVector; +TYPED_TEST(SmallVectorTest, ConstVectorTest) { + const TypeParam constVector; EXPECT_EQ(0u, constVector.size()); EXPECT_TRUE(constVector.empty()); @@ -391,26 +450,40 @@ TEST_F(SmallVectorTest, ConstVectorTest) { } // Direct array access. -TEST_F(SmallVectorTest, DirectVectorTest) { - EXPECT_EQ(0u, theVector.size()); - EXPECT_LE(4u, theVector.capacity()); +TYPED_TEST(SmallVectorTest, DirectVectorTest) { + EXPECT_EQ(0u, this->theVector.size()); + this->theVector.reserve(4); + EXPECT_LE(4u, this->theVector.capacity()); EXPECT_EQ(0, Constructable::getNumConstructorCalls()); - theVector.end()[0] = 1; - theVector.end()[1] = 2; - theVector.end()[2] = 3; - theVector.end()[3] = 4; - theVector.set_size(4); - EXPECT_EQ(4u, theVector.size()); + this->theVector.end()[0] = 1; + this->theVector.end()[1] = 2; + this->theVector.end()[2] = 3; + this->theVector.end()[3] = 4; + this->theVector.set_size(4); + EXPECT_EQ(4u, this->theVector.size()); EXPECT_EQ(4, Constructable::getNumConstructorCalls()); - EXPECT_EQ(1, theVector[0].getValue()); - EXPECT_EQ(2, theVector[1].getValue()); - EXPECT_EQ(3, theVector[2].getValue()); - EXPECT_EQ(4, theVector[3].getValue()); + EXPECT_EQ(1, this->theVector[0].getValue()); + EXPECT_EQ(2, this->theVector[1].getValue()); + EXPECT_EQ(3, this->theVector[2].getValue()); + EXPECT_EQ(4, this->theVector[3].getValue()); } -TEST_F(SmallVectorTest, IteratorTest) { +TYPED_TEST(SmallVectorTest, IteratorTest) { std::list<int> L; - theVector.insert(theVector.end(), L.begin(), L.end()); + this->theVector.insert(this->theVector.end(), L.begin(), L.end()); +} + +struct notassignable { + int &x; + notassignable(int &x) : x(x) {} +}; + +TEST(SmallVectorCustomTest, NoAssignTest) { + int x = 0; + SmallVector<notassignable, 2> vec; + vec.push_back(notassignable(x)); + x = 42; + EXPECT_EQ(42, vec.pop_back_val().x); } } diff --git a/unittests/ADT/SparseSetTest.cpp b/unittests/ADT/SparseSetTest.cpp index a6ea757..eb0e0db 100644 --- a/unittests/ADT/SparseSetTest.cpp +++ b/unittests/ADT/SparseSetTest.cpp @@ -161,7 +161,7 @@ TEST(SparseSetTest, MultipleEntrySet) { struct Alt { unsigned Value; explicit Alt(unsigned x) : Value(x) {} - unsigned getSparseSetKey() const { return Value - 1000; } + unsigned getSparseSetIndex() const { return Value - 1000; } }; TEST(SparseSetTest, AltStructSet) { diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp index 2ae5820..5bb65cb 100644 --- a/unittests/ADT/StringMapTest.cpp +++ b/unittests/ADT/StringMapTest.cpp @@ -75,7 +75,6 @@ const std::string StringMapTest::testKeyStr(testKey); // Empty map tests. TEST_F(StringMapTest, EmptyMapTest) { - SCOPED_TRACE("EmptyMapTest"); assertEmptyMap(); } @@ -102,14 +101,12 @@ TEST_F(StringMapTest, ConstEmptyMapTest) { // A map with a single entry. TEST_F(StringMapTest, SingleEntryMapTest) { - SCOPED_TRACE("SingleEntryMapTest"); testMap[testKey] = testValue; assertSingleItemMap(); } // Test clear() method. TEST_F(StringMapTest, ClearTest) { - SCOPED_TRACE("ClearTest"); testMap[testKey] = testValue; testMap.clear(); assertEmptyMap(); @@ -117,7 +114,6 @@ TEST_F(StringMapTest, ClearTest) { // Test erase(iterator) method. TEST_F(StringMapTest, EraseIteratorTest) { - SCOPED_TRACE("EraseIteratorTest"); testMap[testKey] = testValue; testMap.erase(testMap.begin()); assertEmptyMap(); @@ -125,7 +121,6 @@ TEST_F(StringMapTest, EraseIteratorTest) { // Test erase(value) method. TEST_F(StringMapTest, EraseValueTest) { - SCOPED_TRACE("EraseValueTest"); testMap[testKey] = testValue; testMap.erase(testKey); assertEmptyMap(); @@ -133,13 +128,34 @@ TEST_F(StringMapTest, EraseValueTest) { // Test inserting two values and erasing one. TEST_F(StringMapTest, InsertAndEraseTest) { - SCOPED_TRACE("InsertAndEraseTest"); testMap[testKey] = testValue; testMap["otherKey"] = 2; testMap.erase("otherKey"); assertSingleItemMap(); } +TEST_F(StringMapTest, SmallFullMapTest) { + // StringMap has a tricky corner case when the map is small (<8 buckets) and + // it fills up through a balanced pattern of inserts and erases. This can + // lead to inf-loops in some cases (PR13148) so we test it explicitly here. + llvm::StringMap<int> Map(2); + + Map["eins"] = 1; + Map["zwei"] = 2; + Map["drei"] = 3; + Map.erase("drei"); + Map.erase("eins"); + Map["veir"] = 4; + Map["funf"] = 5; + + EXPECT_EQ(3u, Map.size()); + EXPECT_EQ(0, Map.lookup("eins")); + EXPECT_EQ(2, Map.lookup("zwei")); + EXPECT_EQ(0, Map.lookup("drei")); + EXPECT_EQ(4, Map.lookup("veir")); + EXPECT_EQ(5, Map.lookup("funf")); +} + // A more complex iteration test. TEST_F(StringMapTest, IterationTest) { bool visited[100]; diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp index cc7a7fb..315eacb 100644 --- a/unittests/ADT/StringRefTest.cpp +++ b/unittests/ADT/StringRefTest.cpp @@ -221,6 +221,30 @@ TEST(StringRefTest, Split2) { EXPECT_TRUE(parts == expected); } +TEST(StringRefTest, Trim) { + StringRef Str0("hello"); + StringRef Str1(" hello "); + StringRef Str2(" hello "); + + EXPECT_EQ(StringRef("hello"), Str0.rtrim()); + EXPECT_EQ(StringRef(" hello"), Str1.rtrim()); + EXPECT_EQ(StringRef(" hello"), Str2.rtrim()); + EXPECT_EQ(StringRef("hello"), Str0.ltrim()); + EXPECT_EQ(StringRef("hello "), Str1.ltrim()); + EXPECT_EQ(StringRef("hello "), Str2.ltrim()); + EXPECT_EQ(StringRef("hello"), Str0.trim()); + EXPECT_EQ(StringRef("hello"), Str1.trim()); + EXPECT_EQ(StringRef("hello"), Str2.trim()); + + EXPECT_EQ(StringRef("ello"), Str0.trim("hhhhhhhhhhh")); + + EXPECT_EQ(StringRef(""), StringRef("").trim()); + EXPECT_EQ(StringRef(""), StringRef(" ").trim()); + EXPECT_EQ(StringRef("\0", 1), StringRef(" \0 ", 3).trim()); + EXPECT_EQ(StringRef("\0\0", 2), StringRef("\0\0", 2).trim()); + EXPECT_EQ(StringRef("x"), StringRef("\0\0x\0\0", 5).trim(StringRef("\0", 1))); +} + TEST(StringRefTest, StartsWith) { StringRef Str("hello"); EXPECT_TRUE(Str.startswith("he")); @@ -267,6 +291,10 @@ TEST(StringRefTest, Find) { EXPECT_EQ(1U, Str.find_first_not_of('h')); EXPECT_EQ(4U, Str.find_first_not_of("hel")); EXPECT_EQ(StringRef::npos, Str.find_first_not_of("hello")); + + EXPECT_EQ(3U, Str.find_last_not_of('o')); + EXPECT_EQ(1U, Str.find_last_not_of("lo")); + EXPECT_EQ(StringRef::npos, Str.find_last_not_of("helo")); } TEST(StringRefTest, Count) { diff --git a/unittests/ADT/TinyPtrVectorTest.cpp b/unittests/ADT/TinyPtrVectorTest.cpp new file mode 100644 index 0000000..05dd797 --- /dev/null +++ b/unittests/ADT/TinyPtrVectorTest.cpp @@ -0,0 +1,448 @@ +//===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// TinyPtrVector unit tests. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/Support/type_traits.h" +#include <algorithm> +#include <list> +#include <vector> + +using namespace llvm; + +namespace { + +// The world's worst RNG, but it is deterministic and makes it easy to get +// *some* shuffling of elements. +static ptrdiff_t test_shuffle_rng(ptrdiff_t i) { + return (i + i * 33) % i; +} +static ptrdiff_t (*test_shuffle_rng_p)(ptrdiff_t) = &test_shuffle_rng; + +template <typename VectorT> +class TinyPtrVectorTest : public testing::Test { +protected: + typedef typename VectorT::value_type PtrT; + typedef typename remove_pointer<PtrT>::type ValueT; + + VectorT V; + VectorT V2; + + ValueT TestValues[1024]; + std::vector<PtrT> TestPtrs; + + TinyPtrVectorTest() { + for (size_t i = 0, e = array_lengthof(TestValues); i != e; ++i) + TestPtrs.push_back(&TestValues[i]); + + std::random_shuffle(TestPtrs.begin(), TestPtrs.end(), test_shuffle_rng_p); + } + + ArrayRef<PtrT> testArray(size_t N) { + return makeArrayRef(&TestPtrs[0], N); + } + + void appendValues(VectorT &V, ArrayRef<PtrT> Values) { + for (size_t i = 0, e = Values.size(); i != e; ++i) + V.push_back(Values[i]); + } + + void setVectors(ArrayRef<PtrT> Values1, ArrayRef<PtrT> Values2) { + V.clear(); + appendValues(V, Values1); + V2.clear(); + appendValues(V2, Values2); + } + + void expectValues(const VectorT &V, ArrayRef<PtrT> Values) { + EXPECT_EQ(Values.empty(), V.empty()); + EXPECT_EQ(Values.size(), V.size()); + for (size_t i = 0, e = Values.size(); i != e; ++i) { + EXPECT_EQ(Values[i], V[i]); + EXPECT_EQ(Values[i], *llvm::next(V.begin(), i)); + } + EXPECT_EQ(V.end(), llvm::next(V.begin(), Values.size())); + } +}; + +typedef ::testing::Types<TinyPtrVector<int*>, + TinyPtrVector<double*> + > TinyPtrVectorTestTypes; +TYPED_TEST_CASE(TinyPtrVectorTest, TinyPtrVectorTestTypes); + +TYPED_TEST(TinyPtrVectorTest, EmptyTest) { + this->expectValues(this->V, this->testArray(0)); +} + +TYPED_TEST(TinyPtrVectorTest, PushPopBack) { + this->V.push_back(this->TestPtrs[0]); + this->expectValues(this->V, this->testArray(1)); + this->V.push_back(this->TestPtrs[1]); + this->expectValues(this->V, this->testArray(2)); + this->V.push_back(this->TestPtrs[2]); + this->expectValues(this->V, this->testArray(3)); + this->V.push_back(this->TestPtrs[3]); + this->expectValues(this->V, this->testArray(4)); + this->V.push_back(this->TestPtrs[4]); + this->expectValues(this->V, this->testArray(5)); + + // Pop and clobber a few values to keep things interesting. + this->V.pop_back(); + this->expectValues(this->V, this->testArray(4)); + this->V.pop_back(); + this->expectValues(this->V, this->testArray(3)); + this->TestPtrs[3] = &this->TestValues[42]; + this->TestPtrs[4] = &this->TestValues[43]; + this->V.push_back(this->TestPtrs[3]); + this->expectValues(this->V, this->testArray(4)); + this->V.push_back(this->TestPtrs[4]); + this->expectValues(this->V, this->testArray(5)); + + this->V.pop_back(); + this->expectValues(this->V, this->testArray(4)); + this->V.pop_back(); + this->expectValues(this->V, this->testArray(3)); + this->V.pop_back(); + this->expectValues(this->V, this->testArray(2)); + this->V.pop_back(); + this->expectValues(this->V, this->testArray(1)); + this->V.pop_back(); + this->expectValues(this->V, this->testArray(0)); + + this->appendValues(this->V, this->testArray(42)); + this->expectValues(this->V, this->testArray(42)); +} + +TYPED_TEST(TinyPtrVectorTest, ClearTest) { + this->expectValues(this->V, this->testArray(0)); + this->V.clear(); + this->expectValues(this->V, this->testArray(0)); + + this->appendValues(this->V, this->testArray(1)); + this->expectValues(this->V, this->testArray(1)); + this->V.clear(); + this->expectValues(this->V, this->testArray(0)); + + this->appendValues(this->V, this->testArray(42)); + this->expectValues(this->V, this->testArray(42)); + this->V.clear(); + this->expectValues(this->V, this->testArray(0)); +} + +TYPED_TEST(TinyPtrVectorTest, CopyAndMoveCtorTest) { + this->appendValues(this->V, this->testArray(42)); + TypeParam Copy(this->V); + this->expectValues(Copy, this->testArray(42)); + + // This is a separate copy, and so it shouldn't destroy the original. + Copy.clear(); + this->expectValues(Copy, this->testArray(0)); + this->expectValues(this->V, this->testArray(42)); + + TypeParam Copy2(this->V2); + this->appendValues(Copy2, this->testArray(42)); + this->expectValues(Copy2, this->testArray(42)); + this->expectValues(this->V2, this->testArray(0)); + +#if LLVM_USE_RVALUE_REFERENCES + TypeParam Move(std::move(Copy2)); + this->expectValues(Move, this->testArray(42)); + this->expectValues(Copy2, this->testArray(0)); +#endif +} + +TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { + this->V = this->V2; + this->expectValues(this->V, this->testArray(0)); + this->expectValues(this->V2, this->testArray(0)); +#if LLVM_USE_RVALUE_REFERENCES + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(0)); +#endif + + this->setVectors(this->testArray(1), this->testArray(0)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(0)); + this->expectValues(this->V2, this->testArray(0)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(1), this->testArray(0)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(0)); +#endif + + this->setVectors(this->testArray(2), this->testArray(0)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(0)); + this->expectValues(this->V2, this->testArray(0)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(2), this->testArray(0)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(0)); +#endif + + this->setVectors(this->testArray(42), this->testArray(0)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(0)); + this->expectValues(this->V2, this->testArray(0)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(42), this->testArray(0)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(0)); +#endif + + this->setVectors(this->testArray(0), this->testArray(1)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(1)); + this->expectValues(this->V2, this->testArray(1)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(0), this->testArray(1)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(1)); +#endif + + this->setVectors(this->testArray(0), this->testArray(2)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(2)); + this->expectValues(this->V2, this->testArray(2)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(0), this->testArray(2)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(2)); +#endif + + this->setVectors(this->testArray(0), this->testArray(42)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(42)); + this->expectValues(this->V2, this->testArray(42)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(0), this->testArray(42)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(42)); +#endif + + this->setVectors(this->testArray(1), this->testArray(1)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(1)); + this->expectValues(this->V2, this->testArray(1)); +#if LLVM_USE_RVALUE_REFERENCES + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(1)); +#endif + + this->setVectors(this->testArray(1), this->testArray(2)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(2)); + this->expectValues(this->V2, this->testArray(2)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(1), this->testArray(2)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(2)); +#endif + + this->setVectors(this->testArray(1), this->testArray(42)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(42)); + this->expectValues(this->V2, this->testArray(42)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(1), this->testArray(42)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(42)); +#endif + + this->setVectors(this->testArray(2), this->testArray(1)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(1)); + this->expectValues(this->V2, this->testArray(1)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(2), this->testArray(1)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(1)); +#endif + + this->setVectors(this->testArray(2), this->testArray(2)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(2)); + this->expectValues(this->V2, this->testArray(2)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(2), this->testArray(2)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(2)); +#endif + + this->setVectors(this->testArray(2), this->testArray(42)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(42)); + this->expectValues(this->V2, this->testArray(42)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(2), this->testArray(42)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(42)); +#endif + + this->setVectors(this->testArray(42), this->testArray(1)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(1)); + this->expectValues(this->V2, this->testArray(1)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(42), this->testArray(1)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(1)); +#endif + + this->setVectors(this->testArray(42), this->testArray(2)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(2)); + this->expectValues(this->V2, this->testArray(2)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(42), this->testArray(2)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(2)); +#endif + + this->setVectors(this->testArray(42), this->testArray(42)); + this->V = this->V2; + this->expectValues(this->V, this->testArray(42)); + this->expectValues(this->V2, this->testArray(42)); +#if LLVM_USE_RVALUE_REFERENCES + this->setVectors(this->testArray(42), this->testArray(42)); + this->V = std::move(this->V2); + this->expectValues(this->V, this->testArray(42)); +#endif +} + +TYPED_TEST(TinyPtrVectorTest, EraseTest) { + this->appendValues(this->V, this->testArray(1)); + this->expectValues(this->V, this->testArray(1)); + this->V.erase(this->V.begin()); + this->expectValues(this->V, this->testArray(0)); + + this->appendValues(this->V, this->testArray(42)); + this->expectValues(this->V, this->testArray(42)); + this->V.erase(this->V.begin()); + this->TestPtrs.erase(this->TestPtrs.begin()); + this->expectValues(this->V, this->testArray(41)); + this->V.erase(llvm::next(this->V.begin(), 1)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 1)); + this->expectValues(this->V, this->testArray(40)); + this->V.erase(llvm::next(this->V.begin(), 2)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 2)); + this->expectValues(this->V, this->testArray(39)); + this->V.erase(llvm::next(this->V.begin(), 5)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 5)); + this->expectValues(this->V, this->testArray(38)); + this->V.erase(llvm::next(this->V.begin(), 13)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 13)); + this->expectValues(this->V, this->testArray(37)); + + typename TypeParam::iterator I = this->V.begin(); + do { + I = this->V.erase(I); + } while (I != this->V.end()); + this->expectValues(this->V, this->testArray(0)); +} + +TYPED_TEST(TinyPtrVectorTest, EraseRangeTest) { + this->appendValues(this->V, this->testArray(1)); + this->expectValues(this->V, this->testArray(1)); + this->V.erase(this->V.begin(), this->V.begin()); + this->expectValues(this->V, this->testArray(1)); + this->V.erase(this->V.end(), this->V.end()); + this->expectValues(this->V, this->testArray(1)); + this->V.erase(this->V.begin(), this->V.end()); + this->expectValues(this->V, this->testArray(0)); + + this->appendValues(this->V, this->testArray(42)); + this->expectValues(this->V, this->testArray(42)); + this->V.erase(this->V.begin(), llvm::next(this->V.begin(), 1)); + this->TestPtrs.erase(this->TestPtrs.begin(), + llvm::next(this->TestPtrs.begin(), 1)); + this->expectValues(this->V, this->testArray(41)); + this->V.erase(llvm::next(this->V.begin(), 1), llvm::next(this->V.begin(), 2)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 1), + llvm::next(this->TestPtrs.begin(), 2)); + this->expectValues(this->V, this->testArray(40)); + this->V.erase(llvm::next(this->V.begin(), 2), llvm::next(this->V.begin(), 4)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 2), + llvm::next(this->TestPtrs.begin(), 4)); + this->expectValues(this->V, this->testArray(38)); + this->V.erase(llvm::next(this->V.begin(), 5), llvm::next(this->V.begin(), 10)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 5), + llvm::next(this->TestPtrs.begin(), 10)); + this->expectValues(this->V, this->testArray(33)); + this->V.erase(llvm::next(this->V.begin(), 13), llvm::next(this->V.begin(), 26)); + this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 13), + llvm::next(this->TestPtrs.begin(), 26)); + this->expectValues(this->V, this->testArray(20)); + this->V.erase(llvm::next(this->V.begin(), 7), this->V.end()); + this->expectValues(this->V, this->testArray(7)); + this->V.erase(this->V.begin(), this->V.end()); + this->expectValues(this->V, this->testArray(0)); +} + +TYPED_TEST(TinyPtrVectorTest, Insert) { + this->V.insert(this->V.end(), this->TestPtrs[0]); + this->expectValues(this->V, this->testArray(1)); + this->V.clear(); + this->appendValues(this->V, this->testArray(4)); + this->expectValues(this->V, this->testArray(4)); + this->V.insert(this->V.end(), this->TestPtrs[4]); + this->expectValues(this->V, this->testArray(5)); + this->V.insert(this->V.begin(), this->TestPtrs[42]); + this->TestPtrs.insert(this->TestPtrs.begin(), this->TestPtrs[42]); + this->expectValues(this->V, this->testArray(6)); + this->V.insert(llvm::next(this->V.begin(), 3), this->TestPtrs[43]); + this->TestPtrs.insert(llvm::next(this->TestPtrs.begin(), 3), + this->TestPtrs[43]); + this->expectValues(this->V, this->testArray(7)); +} + +TYPED_TEST(TinyPtrVectorTest, InsertRange) { + this->V.insert(this->V.end(), this->TestPtrs.begin(), this->TestPtrs.begin()); + this->expectValues(this->V, this->testArray(0)); + this->V.insert(this->V.begin(), this->TestPtrs.begin(), + this->TestPtrs.begin()); + this->expectValues(this->V, this->testArray(0)); + this->V.insert(this->V.end(), this->TestPtrs.end(), this->TestPtrs.end()); + this->expectValues(this->V, this->testArray(0)); + this->V.insert(this->V.end(), this->TestPtrs.begin(), + llvm::next(this->TestPtrs.begin())); + this->expectValues(this->V, this->testArray(1)); + this->V.clear(); + this->V.insert(this->V.end(), this->TestPtrs.begin(), + llvm::next(this->TestPtrs.begin(), 2)); + this->expectValues(this->V, this->testArray(2)); + this->V.clear(); + this->V.insert(this->V.end(), this->TestPtrs.begin(), + llvm::next(this->TestPtrs.begin(), 42)); + this->expectValues(this->V, this->testArray(42)); + this->V.clear(); + this->V.insert(this->V.end(), + llvm::next(this->TestPtrs.begin(), 5), + llvm::next(this->TestPtrs.begin(), 13)); + this->V.insert(this->V.begin(), + llvm::next(this->TestPtrs.begin(), 0), + llvm::next(this->TestPtrs.begin(), 3)); + this->V.insert(llvm::next(this->V.begin(), 2), + llvm::next(this->TestPtrs.begin(), 2), + llvm::next(this->TestPtrs.begin(), 4)); + this->V.erase(llvm::next(this->V.begin(), 4)); + this->V.insert(llvm::next(this->V.begin(), 4), + llvm::next(this->TestPtrs.begin(), 4), + llvm::next(this->TestPtrs.begin(), 5)); + this->expectValues(this->V, this->testArray(13)); +} + +} diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index 479046e..967437c 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -353,9 +353,9 @@ TEST(TripleTest, BitWidthArchVariants) { EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::ppc64, T.get64BitArchVariant().getArch()); - T.setArch(Triple::ptx32); - EXPECT_EQ(Triple::ptx32, T.get32BitArchVariant().getArch()); - EXPECT_EQ(Triple::ptx64, T.get64BitArchVariant().getArch()); + T.setArch(Triple::nvptx); + EXPECT_EQ(Triple::nvptx, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::nvptx64, T.get64BitArchVariant().getArch()); T.setArch(Triple::sparc); EXPECT_EQ(Triple::sparc, T.get32BitArchVariant().getArch()); @@ -377,9 +377,9 @@ TEST(TripleTest, BitWidthArchVariants) { EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::ppc64, T.get64BitArchVariant().getArch()); - T.setArch(Triple::ptx64); - EXPECT_EQ(Triple::ptx32, T.get32BitArchVariant().getArch()); - EXPECT_EQ(Triple::ptx64, T.get64BitArchVariant().getArch()); + T.setArch(Triple::nvptx64); + EXPECT_EQ(Triple::nvptx, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::nvptx64, T.get64BitArchVariant().getArch()); T.setArch(Triple::sparcv9); EXPECT_EQ(Triple::sparc, T.get32BitArchVariant().getArch()); @@ -390,4 +390,69 @@ TEST(TripleTest, BitWidthArchVariants) { EXPECT_EQ(Triple::x86_64, T.get64BitArchVariant().getArch()); } +TEST(TripleTest, getOSVersion) { + Triple T; + unsigned Major, Minor, Micro; + + T = Triple("i386-apple-darwin9"); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)5, Minor); + EXPECT_EQ((unsigned)0, Micro); + T.getiOSVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)3, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("x86_64-apple-darwin9"); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)5, Minor); + EXPECT_EQ((unsigned)0, Micro); + T.getiOSVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)3, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("x86_64-apple-macosx"); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)4, Minor); + EXPECT_EQ((unsigned)0, Micro); + T.getiOSVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)3, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("x86_64-apple-macosx10.7"); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)7, Minor); + EXPECT_EQ((unsigned)0, Micro); + T.getiOSVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)3, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("armv7-apple-ios"); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)4, Minor); + EXPECT_EQ((unsigned)0, Micro); + T.getiOSVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)3, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("armv7-apple-ios5.0"); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)4, Minor); + EXPECT_EQ((unsigned)0, Micro); + T.getiOSVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)5, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); +} + } diff --git a/unittests/Analysis/CMakeLists.txt b/unittests/Analysis/CMakeLists.txt new file mode 100644 index 0000000..7991a41 --- /dev/null +++ b/unittests/Analysis/CMakeLists.txt @@ -0,0 +1,7 @@ +set(LLVM_LINK_COMPONENTS + Analysis + ) + +add_llvm_unittest(AnalysisTests + ScalarEvolutionTest.cpp + ) diff --git a/unittests/Analysis/Makefile b/unittests/Analysis/Makefile index f89240e..b548d25 100644 --- a/unittests/Analysis/Makefile +++ b/unittests/Analysis/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. TESTNAME = Analysis -LINK_COMPONENTS := core support target analysis ipa +LINK_COMPONENTS := analysis include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/Bitcode/CMakeLists.txt b/unittests/Bitcode/CMakeLists.txt new file mode 100644 index 0000000..d8f5fe1 --- /dev/null +++ b/unittests/Bitcode/CMakeLists.txt @@ -0,0 +1,8 @@ +set(LLVM_LINK_COMPONENTS + BitReader + BitWriter + ) + +add_llvm_unittest(BitcodeTests + BitReaderTest.cpp + ) diff --git a/unittests/Bitcode/Makefile b/unittests/Bitcode/Makefile index aa437e7..fcec879 100644 --- a/unittests/Bitcode/Makefile +++ b/unittests/Bitcode/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. TESTNAME = Bitcode -LINK_COMPONENTS := core support bitreader bitwriter +LINK_COMPONENTS := bitreader bitwriter include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 78009a8..84bd444 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -1,178 +1,14 @@ -function(add_llvm_unittest test_dirname) - string(REGEX MATCH "([^/]+)$" test_name ${test_dirname}) - if (CMAKE_BUILD_TYPE) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY - ${LLVM_BINARY_DIR}/unittests/${test_dirname}/${CMAKE_BUILD_TYPE}) - else() - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY - ${LLVM_BINARY_DIR}/unittests/${test_dirname}) - endif() - if( NOT LLVM_BUILD_TESTS ) - set(EXCLUDE_FROM_ALL ON) - endif() - add_llvm_executable(${test_name}Tests ${ARGN}) - add_dependencies(UnitTests ${test_name}Tests) - set_target_properties(${test_name}Tests PROPERTIES FOLDER "Tests") -endfunction() - add_custom_target(UnitTests) set_target_properties(UnitTests PROPERTIES FOLDER "Tests") -include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) -add_definitions(-DGTEST_HAS_RTTI=0) -if( LLVM_COMPILER_IS_GCC_COMPATIBLE ) - llvm_replace_compiler_option(CMAKE_CXX_FLAGS "-frtti" "-fno-rtti") -elseif( MSVC ) - llvm_replace_compiler_option(CMAKE_CXX_FLAGS "/GR" "/GR-") -endif() - -if (NOT LLVM_ENABLE_THREADS) - add_definitions(-DGTEST_HAS_PTHREAD=0) -endif() - -if(SUPPORTS_NO_VARIADIC_MACROS_FLAG) - add_definitions("-Wno-variadic-macros") -endif() - -set(LLVM_LINK_COMPONENTS - jit - interpreter - nativecodegen - BitWriter - BitReader - AsmParser - Core - Support - ) - -set(LLVM_USED_LIBS - gtest - gtest_main - LLVMSupport # gtest needs it for raw_ostream. - ) - -add_llvm_unittest(ADT - ADT/APFloatTest.cpp - ADT/APIntTest.cpp - ADT/BitVectorTest.cpp - ADT/DAGDeltaAlgorithmTest.cpp - ADT/DeltaAlgorithmTest.cpp - ADT/DenseMapTest.cpp - ADT/DenseSetTest.cpp - ADT/FoldingSet.cpp - ADT/HashingTest.cpp - ADT/ilistTest.cpp - ADT/ImmutableSetTest.cpp - ADT/IntEqClassesTest.cpp - ADT/IntervalMapTest.cpp - ADT/IntrusiveRefCntPtrTest.cpp - ADT/PackedVectorTest.cpp - ADT/SmallBitVectorTest.cpp - ADT/SmallStringTest.cpp - ADT/SmallVectorTest.cpp - ADT/SparseBitVectorTest.cpp - ADT/SparseSetTest.cpp - ADT/StringMapTest.cpp - ADT/StringRefTest.cpp - ADT/TripleTest.cpp - ADT/TwineTest.cpp - ADT/VariadicFunctionTest.cpp - ) - -add_llvm_unittest(Analysis - Analysis/ScalarEvolutionTest.cpp - ) - -add_llvm_unittest(ExecutionEngine - ExecutionEngine/ExecutionEngineTest.cpp - ) - -if( LLVM_USE_INTEL_JITEVENTS ) - include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} ) - link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} ) - set(ProfileTestSources - ExecutionEngine/JIT/IntelJITEventListenerTest.cpp - ) - set(LLVM_LINK_COMPONENTS - ${LLVM_LINK_COMPONENTS} - IntelJITEvents - ) -endif( LLVM_USE_INTEL_JITEVENTS ) - -if( LLVM_USE_OPROFILE ) - set(ProfileTestSources - ${ProfileTestSources} - ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp - ) - set(LLVM_LINK_COMPONENTS - ${LLVM_LINK_COMPONENTS} - OProfileJIT - ) -endif( LLVM_USE_OPROFILE ) - -set(JITTestsSources - ExecutionEngine/JIT/JITEventListenerTest.cpp - ExecutionEngine/JIT/JITMemoryManagerTest.cpp - ExecutionEngine/JIT/JITTest.cpp - ExecutionEngine/JIT/MultiJITTest.cpp - ${ProfileTestSources} - ) - -if(MSVC) - list(APPEND JITTestsSources ExecutionEngine/JIT/JITTests.def) -endif() - -add_llvm_unittest(ExecutionEngine/JIT ${JITTestsSources}) - -if(MINGW OR CYGWIN) - set_property(TARGET JITTests PROPERTY LINK_FLAGS -Wl,--export-all-symbols) -endif() - -add_llvm_unittest(Transforms/Utils - Transforms/Utils/Cloning.cpp - ) - -set(VMCoreSources - VMCore/ConstantsTest.cpp - VMCore/InstructionsTest.cpp - VMCore/MetadataTest.cpp - VMCore/PassManagerTest.cpp - VMCore/ValueMapTest.cpp - VMCore/VerifierTest.cpp - VMCore/DominatorTreeTest.cpp - ) - -# MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug. -# See issue#331418 in Visual Studio. -if(MSVC AND MSVC_VERSION LESS 1600) - list(REMOVE_ITEM VMCoreSources VMCore/ValueMapTest.cpp) -endif() - -add_llvm_unittest(VMCore ${VMCoreSources}) - -add_llvm_unittest(Bitcode - Bitcode/BitReaderTest.cpp - ) - -set(LLVM_LINK_COMPONENTS - Support - Core - ) +function(add_llvm_unittest test_dirname) + add_unittest(UnitTests ${test_dirname} ${ARGN}) +endfunction() -add_llvm_unittest(Support - Support/AllocatorTest.cpp - Support/Casting.cpp - Support/CommandLineTest.cpp - Support/ConstantRangeTest.cpp - Support/EndianTest.cpp - Support/LeakDetectorTest.cpp - Support/MathExtrasTest.cpp - Support/Path.cpp - Support/raw_ostream_test.cpp - Support/RegexTest.cpp - Support/SwapByteOrderTest.cpp - Support/TimeValue.cpp - Support/TypeBuilderTest.cpp - Support/ValueHandleTest.cpp - Support/YAMLParserTest.cpp - ) +add_subdirectory(ADT) +add_subdirectory(Analysis) +add_subdirectory(ExecutionEngine) +add_subdirectory(Bitcode) +add_subdirectory(Support) +add_subdirectory(Transforms) +add_subdirectory(VMCore) diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt new file mode 100644 index 0000000..5fffadd --- /dev/null +++ b/unittests/ExecutionEngine/CMakeLists.txt @@ -0,0 +1,9 @@ +set(LLVM_LINK_COMPONENTS + interpreter + ) + +add_llvm_unittest(ExecutionEngineTests + ExecutionEngineTest.cpp + ) + +add_subdirectory(JIT) diff --git a/unittests/ExecutionEngine/JIT/CMakeLists.txt b/unittests/ExecutionEngine/JIT/CMakeLists.txt new file mode 100644 index 0000000..d43d72d --- /dev/null +++ b/unittests/ExecutionEngine/JIT/CMakeLists.txt @@ -0,0 +1,57 @@ +set(LLVM_LINK_COMPONENTS + asmparser + bitreader + bitwriter + jit + nativecodegen + ) + +# HACK: Declare a couple of source files as optionally compiled to satisfy the +# missing-file-checker in LLVM's weird CMake build. +set(LLVM_OPTIONAL_SOURCES + IntelJITEventListenerTest.cpp + OProfileJITEventListenerTest.cpp + ) + +if( LLVM_USE_INTEL_JITEVENTS ) + include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} ) + link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} ) + set(ProfileTestSources + IntelJITEventListenerTest.cpp + ) + set(LLVM_LINK_COMPONENTS + ${LLVM_LINK_COMPONENTS} + IntelJITEvents + ) +endif( LLVM_USE_INTEL_JITEVENTS ) + +if( LLVM_USE_OPROFILE ) + set(ProfileTestSources + ${ProfileTestSources} + OProfileJITEventListenerTest.cpp + ) + set(LLVM_LINK_COMPONENTS + ${LLVM_LINK_COMPONENTS} + OProfileJIT + ) +endif( LLVM_USE_OPROFILE ) + +set(JITTestsSources + JITEventListenerTest.cpp + JITMemoryManagerTest.cpp + JITTest.cpp + MultiJITTest.cpp + ${ProfileTestSources} + ) + +if(MSVC) + list(APPEND JITTestsSources JITTests.def) +endif() + +add_llvm_unittest(JITTests + ${JITTestsSources} + ) + +if(MINGW OR CYGWIN) + set_property(TARGET JITTests PROPERTY LINK_FLAGS -Wl,--export-all-symbols) +endif() diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp index f8d8830..333888a 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp @@ -12,10 +12,10 @@ #include "llvm/LLVMContext.h" #include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/TypeBuilder.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/ExecutionEngine/JIT.h" -#include "llvm/Support/TypeBuilder.h" #include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" #include <vector> diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h index 53608cb..5f02b38 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h @@ -10,18 +10,18 @@ #ifndef JIT_EVENT_LISTENER_TEST_COMMON_H #define JIT_EVENT_LISTENER_TEST_COMMON_H -#include "llvm/Analysis/DIBuilder.h" -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/DIBuilder.h" +#include "llvm/DebugInfo.h" +#include "llvm/IRBuilder.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/TypeBuilder.h" #include "llvm/CodeGen/MachineCodeInfo.h" -#include "llvm/Config/config.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Support/IRBuilder.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/TypeBuilder.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Config/config.h" #include "gtest/gtest.h" diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index fa52321..89f7e8e 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -7,29 +7,29 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Assembly/Parser.h" #include "llvm/BasicBlock.h" -#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Constant.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/ExecutionEngine/JIT.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/Function.h" #include "llvm/GlobalValue.h" #include "llvm/GlobalVariable.h" +#include "llvm/IRBuilder.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" -#include "llvm/Support/IRBuilder.h" +#include "llvm/Type.h" +#include "llvm/TypeBuilder.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Assembly/Parser.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/ExecutionEngine/JIT.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TypeBuilder.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/Type.h" +#include "gtest/gtest.h" #include <vector> using namespace llvm; @@ -477,10 +477,11 @@ TEST_F(JITTest, ModuleDeletion) { } #endif // !defined(__arm__) -// ARM and PPC still emit stubs for calls since the target may be too far away -// to call directly. This #if can probably be removed when +// ARM, MIPS and PPC still emit stubs for calls since the target may be +// too far away to call directly. This #if can probably be removed when // http://llvm.org/PR5201 is fixed. -#if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__) +#if !defined(__arm__) && !defined(__mips__) && \ + !defined(__powerpc__) && !defined(__ppc__) typedef int (*FooPtr) (); TEST_F(JITTest, NoStubs) { @@ -554,8 +555,9 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) { #endif } -// ARM doesn't have an implementation of replaceMachineCodeForFunction(), so -// recompileAndRelinkFunction doesn't work. +// ARM does not have an implementation +// of replaceMachineCodeForFunction(), so recompileAndRelinkFunction +// doesn't work. #if !defined(__arm__) TEST_F(JITTest, FunctionIsRecompiledAndRelinked) { Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context), diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile index c404fb0..b535a6b 100644 --- a/unittests/ExecutionEngine/JIT/Makefile +++ b/unittests/ExecutionEngine/JIT/Makefile @@ -9,7 +9,7 @@ LEVEL = ../../.. TESTNAME = JIT -LINK_COMPONENTS := asmparser bitreader bitwriter core jit native support +LINK_COMPONENTS := asmparser bitreader bitwriter jit native include $(LEVEL)/Makefile.config diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile index a0395cd..63508d2 100644 --- a/unittests/ExecutionEngine/Makefile +++ b/unittests/ExecutionEngine/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. TESTNAME = ExecutionEngine -LINK_COMPONENTS := engine interpreter +LINK_COMPONENTS :=interpreter PARALLEL_DIRS = JIT include $(LEVEL)/Makefile.config diff --git a/unittests/Support/AlignOfTest.cpp b/unittests/Support/AlignOfTest.cpp new file mode 100644 index 0000000..c45db2c --- /dev/null +++ b/unittests/Support/AlignOfTest.cpp @@ -0,0 +1,328 @@ +//===- llvm/unittest/Support/AlignOfTest.cpp - Alignment utility tests ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/AlignOf.h" +#include "llvm/Support/Compiler.h" + +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +// Disable warnings about questionable type definitions. +// We're testing that even questionable types work with the alignment utilities. +#ifdef _MSC_VER +#pragma warning(disable:4584) +#endif + +// Define some fixed alignment types to use in these tests. +#if __cplusplus == 201103L || __has_feature(cxx_alignas) +typedef char alignas(1) A1; +typedef char alignas(2) A2; +typedef char alignas(4) A4; +typedef char alignas(8) A8; +#elif defined(__clang__) || defined(__GNUC__) +typedef char A1 __attribute__((aligned(1))); +typedef char A2 __attribute__((aligned(2))); +typedef char A4 __attribute__((aligned(4))); +typedef char A8 __attribute__((aligned(8))); +#elif defined(_MSC_VER) +typedef __declspec(align(1)) char A1; +typedef __declspec(align(2)) char A2; +typedef __declspec(align(4)) char A4; +typedef __declspec(align(8)) char A8; +#else +# error No supported align as directive. +#endif + +// Wrap the forced aligned types in structs to hack around compiler bugs. +struct SA1 { A1 a; }; +struct SA2 { A2 a; }; +struct SA4 { A4 a; }; +struct SA8 { A8 a; }; + +struct S1 {}; +struct S2 { char a; }; +struct S3 { int x; }; +struct S4 { double y; }; +struct S5 { A1 a1; A2 a2; A4 a4; A8 a8; }; +struct S6 { double f(); }; +struct D1 : S1 {}; +struct D2 : S6 { float g(); }; +struct D3 : S2 {}; +struct D4 : S2 { int x; }; +struct D5 : S3 { char c; }; +struct D6 : S2, S3 {}; +struct D7 : S1, S3 {}; +struct D8 : S1, D4, D5 { double x[2]; }; +struct D9 : S1, D1 { S1 s1; }; +struct V1 { virtual ~V1(); }; +struct V2 { int x; virtual ~V2(); }; +struct V3 : V1 { virtual ~V3(); }; +struct V4 : virtual V2 { int y; virtual ~V4(); }; +struct V5 : V4, V3 { double z; virtual ~V5(); }; +struct V6 : S1 { virtual ~V6(); }; +struct V7 : virtual V2, virtual V6 { virtual ~V7(); }; +struct V8 : V5, virtual V6, V7 { double zz; virtual ~V8(); }; + +// Ensure alignment is a compile-time constant. +char LLVM_ATTRIBUTE_UNUSED test_arr1 + [AlignOf<char>::Alignment > 0] + [AlignOf<short>::Alignment > 0] + [AlignOf<int>::Alignment > 0] + [AlignOf<long>::Alignment > 0] + [AlignOf<long long>::Alignment > 0] + [AlignOf<float>::Alignment > 0] + [AlignOf<double>::Alignment > 0] + [AlignOf<long double>::Alignment > 0] + [AlignOf<void *>::Alignment > 0] + [AlignOf<int *>::Alignment > 0] + [AlignOf<double (*)(double)>::Alignment > 0] + [AlignOf<double (S6::*)()>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr2 + [AlignOf<A1>::Alignment > 0] + [AlignOf<A2>::Alignment > 0] + [AlignOf<A4>::Alignment > 0] + [AlignOf<A8>::Alignment > 0] + [AlignOf<SA1>::Alignment > 0] + [AlignOf<SA2>::Alignment > 0] + [AlignOf<SA4>::Alignment > 0] + [AlignOf<SA8>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr3 + [AlignOf<S1>::Alignment > 0] + [AlignOf<S2>::Alignment > 0] + [AlignOf<S3>::Alignment > 0] + [AlignOf<S4>::Alignment > 0] + [AlignOf<S5>::Alignment > 0] + [AlignOf<S6>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr4 + [AlignOf<D1>::Alignment > 0] + [AlignOf<D2>::Alignment > 0] + [AlignOf<D3>::Alignment > 0] + [AlignOf<D4>::Alignment > 0] + [AlignOf<D5>::Alignment > 0] + [AlignOf<D6>::Alignment > 0] + [AlignOf<D7>::Alignment > 0] + [AlignOf<D8>::Alignment > 0] + [AlignOf<D9>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr5 + [AlignOf<V1>::Alignment > 0] + [AlignOf<V2>::Alignment > 0] + [AlignOf<V3>::Alignment > 0] + [AlignOf<V4>::Alignment > 0] + [AlignOf<V5>::Alignment > 0] + [AlignOf<V6>::Alignment > 0] + [AlignOf<V7>::Alignment > 0] + [AlignOf<V8>::Alignment > 0]; + +TEST(AlignOfTest, BasicAlignmentInvariants) { + // For a very strange reason, many compilers do not support this. Both Clang + // and GCC fail to align these properly. + EXPECT_EQ(1u, alignOf<A1>()); +#if 0 + EXPECT_EQ(2u, alignOf<A2>()); + EXPECT_EQ(4u, alignOf<A4>()); + EXPECT_EQ(8u, alignOf<A8>()); +#endif + + // But once wrapped in structs, the alignment is correctly managed. + EXPECT_LE(1u, alignOf<SA1>()); + EXPECT_LE(2u, alignOf<SA2>()); + EXPECT_LE(4u, alignOf<SA4>()); + EXPECT_LE(8u, alignOf<SA8>()); + + EXPECT_EQ(1u, alignOf<char>()); + EXPECT_LE(alignOf<char>(), alignOf<short>()); + EXPECT_LE(alignOf<short>(), alignOf<int>()); + EXPECT_LE(alignOf<int>(), alignOf<long>()); + EXPECT_LE(alignOf<long>(), alignOf<long long>()); + EXPECT_LE(alignOf<char>(), alignOf<float>()); + EXPECT_LE(alignOf<float>(), alignOf<double>()); + EXPECT_LE(alignOf<char>(), alignOf<long double>()); + EXPECT_LE(alignOf<char>(), alignOf<void *>()); + EXPECT_EQ(alignOf<void *>(), alignOf<int *>()); + EXPECT_LE(alignOf<char>(), alignOf<S1>()); + EXPECT_LE(alignOf<S1>(), alignOf<S2>()); + EXPECT_LE(alignOf<S1>(), alignOf<S3>()); + EXPECT_LE(alignOf<S1>(), alignOf<S4>()); + EXPECT_LE(alignOf<S1>(), alignOf<S5>()); + EXPECT_LE(alignOf<S1>(), alignOf<S6>()); + EXPECT_LE(alignOf<S1>(), alignOf<D1>()); + EXPECT_LE(alignOf<S1>(), alignOf<D2>()); + EXPECT_LE(alignOf<S1>(), alignOf<D3>()); + EXPECT_LE(alignOf<S1>(), alignOf<D4>()); + EXPECT_LE(alignOf<S1>(), alignOf<D5>()); + EXPECT_LE(alignOf<S1>(), alignOf<D6>()); + EXPECT_LE(alignOf<S1>(), alignOf<D7>()); + EXPECT_LE(alignOf<S1>(), alignOf<D8>()); + EXPECT_LE(alignOf<S1>(), alignOf<D9>()); + EXPECT_LE(alignOf<S1>(), alignOf<V1>()); + EXPECT_LE(alignOf<V1>(), alignOf<V2>()); + EXPECT_LE(alignOf<V1>(), alignOf<V3>()); + EXPECT_LE(alignOf<V1>(), alignOf<V4>()); + EXPECT_LE(alignOf<V1>(), alignOf<V5>()); + EXPECT_LE(alignOf<V1>(), alignOf<V6>()); + EXPECT_LE(alignOf<V1>(), alignOf<V7>()); + EXPECT_LE(alignOf<V1>(), alignOf<V8>()); +} + +TEST(AlignOfTest, BasicAlignedArray) { + // Note: this code exclusively uses the struct-wrapped arbitrarily aligned + // types because of the bugs mentioned above where GCC and Clang both + // disregard the arbitrary alignment specifier until the type is used to + // declare a member of a struct. + EXPECT_LE(1u, alignOf<AlignedCharArray<SA1>::union_type>()); + EXPECT_LE(2u, alignOf<AlignedCharArray<SA2>::union_type>()); + EXPECT_LE(4u, alignOf<AlignedCharArray<SA4>::union_type>()); + EXPECT_LE(8u, alignOf<AlignedCharArray<SA8>::union_type>()); + + EXPECT_LE(1u, sizeof(AlignedCharArray<SA1>::union_type)); + EXPECT_LE(2u, sizeof(AlignedCharArray<SA2>::union_type)); + EXPECT_LE(4u, sizeof(AlignedCharArray<SA4>::union_type)); + EXPECT_LE(8u, sizeof(AlignedCharArray<SA8>::union_type)); + + EXPECT_EQ(1u, (alignOf<AlignedCharArray<SA1>::union_type>())); + EXPECT_EQ(2u, (alignOf<AlignedCharArray<SA1, SA2>::union_type>())); + EXPECT_EQ(4u, (alignOf<AlignedCharArray<SA1, SA2, SA4>::union_type>())); + EXPECT_EQ(8u, (alignOf<AlignedCharArray<SA1, SA2, SA4, SA8>::union_type>())); + + EXPECT_EQ(1u, sizeof(AlignedCharArray<SA1>::union_type)); + EXPECT_EQ(2u, sizeof(AlignedCharArray<SA1, SA2>::union_type)); + EXPECT_EQ(4u, sizeof(AlignedCharArray<SA1, SA2, SA4>::union_type)); + EXPECT_EQ(8u, sizeof(AlignedCharArray<SA1, SA2, SA4, SA8>::union_type)); + + EXPECT_EQ(1u, (alignOf<AlignedCharArray<SA1[1]>::union_type>())); + EXPECT_EQ(2u, (alignOf<AlignedCharArray<SA1[2], SA2[1]>::union_type>())); + EXPECT_EQ(4u, (alignOf<AlignedCharArray<SA1[42], SA2[55], + SA4[13]>::union_type>())); + EXPECT_EQ(8u, (alignOf<AlignedCharArray<SA1[2], SA2[1], + SA4, SA8>::union_type>())); + + EXPECT_EQ(1u, sizeof(AlignedCharArray<SA1[1]>::union_type)); + EXPECT_EQ(2u, sizeof(AlignedCharArray<SA1[2], SA2[1]>::union_type)); + EXPECT_EQ(4u, sizeof(AlignedCharArray<SA1[3], SA2[2], SA4>::union_type)); + EXPECT_EQ(16u, sizeof(AlignedCharArray<SA1, SA2[3], + SA4[3], SA8>::union_type)); + + // For other tests we simply assert that the alignment of the union mathes + // that of the fundamental type and hope that we have any weird type + // productions that would trigger bugs. + EXPECT_EQ(alignOf<char>(), alignOf<AlignedCharArray<char>::union_type>()); + EXPECT_EQ(alignOf<short>(), alignOf<AlignedCharArray<short>::union_type>()); + EXPECT_EQ(alignOf<int>(), alignOf<AlignedCharArray<int>::union_type>()); + EXPECT_EQ(alignOf<long>(), alignOf<AlignedCharArray<long>::union_type>()); + EXPECT_EQ(alignOf<long long>(), + alignOf<AlignedCharArray<long long>::union_type>()); + EXPECT_EQ(alignOf<float>(), alignOf<AlignedCharArray<float>::union_type>()); + EXPECT_EQ(alignOf<double>(), alignOf<AlignedCharArray<double>::union_type>()); + EXPECT_EQ(alignOf<long double>(), + alignOf<AlignedCharArray<long double>::union_type>()); + EXPECT_EQ(alignOf<void *>(), alignOf<AlignedCharArray<void *>::union_type>()); + EXPECT_EQ(alignOf<int *>(), alignOf<AlignedCharArray<int *>::union_type>()); + EXPECT_EQ(alignOf<double (*)(double)>(), + alignOf<AlignedCharArray<double (*)(double)>::union_type>()); + EXPECT_EQ(alignOf<double (S6::*)()>(), + alignOf<AlignedCharArray<double (S6::*)()>::union_type>()); + EXPECT_EQ(alignOf<S1>(), alignOf<AlignedCharArray<S1>::union_type>()); + EXPECT_EQ(alignOf<S2>(), alignOf<AlignedCharArray<S2>::union_type>()); + EXPECT_EQ(alignOf<S3>(), alignOf<AlignedCharArray<S3>::union_type>()); + EXPECT_EQ(alignOf<S4>(), alignOf<AlignedCharArray<S4>::union_type>()); + EXPECT_EQ(alignOf<S5>(), alignOf<AlignedCharArray<S5>::union_type>()); + EXPECT_EQ(alignOf<S6>(), alignOf<AlignedCharArray<S6>::union_type>()); + EXPECT_EQ(alignOf<D1>(), alignOf<AlignedCharArray<D1>::union_type>()); + EXPECT_EQ(alignOf<D2>(), alignOf<AlignedCharArray<D2>::union_type>()); + EXPECT_EQ(alignOf<D3>(), alignOf<AlignedCharArray<D3>::union_type>()); + EXPECT_EQ(alignOf<D4>(), alignOf<AlignedCharArray<D4>::union_type>()); + EXPECT_EQ(alignOf<D5>(), alignOf<AlignedCharArray<D5>::union_type>()); + EXPECT_EQ(alignOf<D6>(), alignOf<AlignedCharArray<D6>::union_type>()); + EXPECT_EQ(alignOf<D7>(), alignOf<AlignedCharArray<D7>::union_type>()); + EXPECT_EQ(alignOf<D8>(), alignOf<AlignedCharArray<D8>::union_type>()); + EXPECT_EQ(alignOf<D9>(), alignOf<AlignedCharArray<D9>::union_type>()); + EXPECT_EQ(alignOf<V1>(), alignOf<AlignedCharArray<V1>::union_type>()); + EXPECT_EQ(alignOf<V2>(), alignOf<AlignedCharArray<V2>::union_type>()); + EXPECT_EQ(alignOf<V3>(), alignOf<AlignedCharArray<V3>::union_type>()); + EXPECT_EQ(alignOf<V4>(), alignOf<AlignedCharArray<V4>::union_type>()); + EXPECT_EQ(alignOf<V5>(), alignOf<AlignedCharArray<V5>::union_type>()); + EXPECT_EQ(alignOf<V6>(), alignOf<AlignedCharArray<V6>::union_type>()); + EXPECT_EQ(alignOf<V7>(), alignOf<AlignedCharArray<V7>::union_type>()); + + // Some versions of MSVC get this wrong somewhat disturbingly. The failure + // appears to be benign: alignOf<V8>() produces a preposterous value: 12 +#ifndef _MSC_VER + EXPECT_EQ(alignOf<V8>(), alignOf<AlignedCharArray<V8>::union_type>()); +#endif + + EXPECT_EQ(sizeof(char), sizeof(AlignedCharArray<char>::union_type)); + EXPECT_EQ(sizeof(char[1]), sizeof(AlignedCharArray<char[1]>::union_type)); + EXPECT_EQ(sizeof(char[2]), sizeof(AlignedCharArray<char[2]>::union_type)); + EXPECT_EQ(sizeof(char[3]), sizeof(AlignedCharArray<char[3]>::union_type)); + EXPECT_EQ(sizeof(char[4]), sizeof(AlignedCharArray<char[4]>::union_type)); + EXPECT_EQ(sizeof(char[5]), sizeof(AlignedCharArray<char[5]>::union_type)); + EXPECT_EQ(sizeof(char[8]), sizeof(AlignedCharArray<char[8]>::union_type)); + EXPECT_EQ(sizeof(char[13]), sizeof(AlignedCharArray<char[13]>::union_type)); + EXPECT_EQ(sizeof(char[16]), sizeof(AlignedCharArray<char[16]>::union_type)); + EXPECT_EQ(sizeof(char[21]), sizeof(AlignedCharArray<char[21]>::union_type)); + EXPECT_EQ(sizeof(char[32]), sizeof(AlignedCharArray<char[32]>::union_type)); + EXPECT_EQ(sizeof(short), sizeof(AlignedCharArray<short>::union_type)); + EXPECT_EQ(sizeof(int), sizeof(AlignedCharArray<int>::union_type)); + EXPECT_EQ(sizeof(long), sizeof(AlignedCharArray<long>::union_type)); + EXPECT_EQ(sizeof(long long), + sizeof(AlignedCharArray<long long>::union_type)); + EXPECT_EQ(sizeof(float), sizeof(AlignedCharArray<float>::union_type)); + EXPECT_EQ(sizeof(double), sizeof(AlignedCharArray<double>::union_type)); + EXPECT_EQ(sizeof(long double), + sizeof(AlignedCharArray<long double>::union_type)); + EXPECT_EQ(sizeof(void *), sizeof(AlignedCharArray<void *>::union_type)); + EXPECT_EQ(sizeof(int *), sizeof(AlignedCharArray<int *>::union_type)); + EXPECT_EQ(sizeof(double (*)(double)), + sizeof(AlignedCharArray<double (*)(double)>::union_type)); + EXPECT_EQ(sizeof(double (S6::*)()), + sizeof(AlignedCharArray<double (S6::*)()>::union_type)); + EXPECT_EQ(sizeof(S1), sizeof(AlignedCharArray<S1>::union_type)); + EXPECT_EQ(sizeof(S2), sizeof(AlignedCharArray<S2>::union_type)); + EXPECT_EQ(sizeof(S3), sizeof(AlignedCharArray<S3>::union_type)); + EXPECT_EQ(sizeof(S4), sizeof(AlignedCharArray<S4>::union_type)); + EXPECT_EQ(sizeof(S5), sizeof(AlignedCharArray<S5>::union_type)); + EXPECT_EQ(sizeof(S6), sizeof(AlignedCharArray<S6>::union_type)); + EXPECT_EQ(sizeof(D1), sizeof(AlignedCharArray<D1>::union_type)); + EXPECT_EQ(sizeof(D2), sizeof(AlignedCharArray<D2>::union_type)); + EXPECT_EQ(sizeof(D3), sizeof(AlignedCharArray<D3>::union_type)); + EXPECT_EQ(sizeof(D4), sizeof(AlignedCharArray<D4>::union_type)); + EXPECT_EQ(sizeof(D5), sizeof(AlignedCharArray<D5>::union_type)); + EXPECT_EQ(sizeof(D6), sizeof(AlignedCharArray<D6>::union_type)); + EXPECT_EQ(sizeof(D7), sizeof(AlignedCharArray<D7>::union_type)); + EXPECT_EQ(sizeof(D8), sizeof(AlignedCharArray<D8>::union_type)); + EXPECT_EQ(sizeof(D9), sizeof(AlignedCharArray<D9>::union_type)); + EXPECT_EQ(sizeof(D9[1]), sizeof(AlignedCharArray<D9[1]>::union_type)); + EXPECT_EQ(sizeof(D9[2]), sizeof(AlignedCharArray<D9[2]>::union_type)); + EXPECT_EQ(sizeof(D9[3]), sizeof(AlignedCharArray<D9[3]>::union_type)); + EXPECT_EQ(sizeof(D9[4]), sizeof(AlignedCharArray<D9[4]>::union_type)); + EXPECT_EQ(sizeof(D9[5]), sizeof(AlignedCharArray<D9[5]>::union_type)); + EXPECT_EQ(sizeof(D9[8]), sizeof(AlignedCharArray<D9[8]>::union_type)); + EXPECT_EQ(sizeof(D9[13]), sizeof(AlignedCharArray<D9[13]>::union_type)); + EXPECT_EQ(sizeof(D9[16]), sizeof(AlignedCharArray<D9[16]>::union_type)); + EXPECT_EQ(sizeof(D9[21]), sizeof(AlignedCharArray<D9[21]>::union_type)); + EXPECT_EQ(sizeof(D9[32]), sizeof(AlignedCharArray<D9[32]>::union_type)); + EXPECT_EQ(sizeof(V1), sizeof(AlignedCharArray<V1>::union_type)); + EXPECT_EQ(sizeof(V2), sizeof(AlignedCharArray<V2>::union_type)); + EXPECT_EQ(sizeof(V3), sizeof(AlignedCharArray<V3>::union_type)); + EXPECT_EQ(sizeof(V4), sizeof(AlignedCharArray<V4>::union_type)); + EXPECT_EQ(sizeof(V5), sizeof(AlignedCharArray<V5>::union_type)); + EXPECT_EQ(sizeof(V6), sizeof(AlignedCharArray<V6>::union_type)); + EXPECT_EQ(sizeof(V7), sizeof(AlignedCharArray<V7>::union_type)); + + // Some versions of MSVC also get this wrong. The failure again appears to be + // benign: sizeof(V8) is only 52 bytes, but our array reserves 56. +#ifndef _MSC_VER + EXPECT_EQ(sizeof(V8), sizeof(AlignedCharArray<V8>::union_type)); +#endif +} + +} diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp index df25642..9c5bd7b 100644 --- a/unittests/Support/BlockFrequencyTest.cpp +++ b/unittests/Support/BlockFrequencyTest.cpp @@ -34,7 +34,7 @@ TEST(BlockFrequencyTest, MaxToHalfMax) { BlockFrequency Freq(UINT64_MAX); BranchProbability Prob(UINT32_MAX / 2, UINT32_MAX); Freq *= Prob; - EXPECT_EQ(Freq.getFrequency(), 9223372034707292159LLu); + EXPECT_EQ(Freq.getFrequency(), 9223372034707292159ULL); } TEST(BlockFrequencyTest, BigToBig) { diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt new file mode 100644 index 0000000..3b9bf84 --- /dev/null +++ b/unittests/Support/CMakeLists.txt @@ -0,0 +1,27 @@ +set(LLVM_LINK_COMPONENTS + Support + Core + ) + +add_llvm_unittest(SupportTests + AlignOfTest.cpp + AllocatorTest.cpp + BlockFrequencyTest.cpp + Casting.cpp + CommandLineTest.cpp + ConstantRangeTest.cpp + DataExtractorTest.cpp + EndianTest.cpp + FileOutputBufferTest.cpp + IntegersSubsetTest.cpp + LeakDetectorTest.cpp + ManagedStatic.cpp + MathExtrasTest.cpp + Path.cpp + raw_ostream_test.cpp + RegexTest.cpp + SwapByteOrderTest.cpp + TimeValue.cpp + ValueHandleTest.cpp + YAMLParserTest.cpp + ) diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index 72fa24a..13e9038 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -55,6 +55,17 @@ TEST(CommandLineTest, ParseEnvironment) { EXPECT_EQ("hello", EnvironmentTestOption); } +// This test used to make valgrind complain +// ("Conditional jump or move depends on uninitialised value(s)") +TEST(CommandLineTest, ParseEnvironmentToLocalVar) { + // Put cl::opt on stack to check for proper initialization of fields. + cl::opt<std::string> EnvironmentTestOptionLocal("env-test-opt-local"); + TempEnvVar TEV(test_env_var, "-env-test-opt-local=hello-local"); + EXPECT_EQ("", EnvironmentTestOptionLocal); + cl::ParseEnvironmentOptions("CommandLineTest", test_env_var); + EXPECT_EQ("hello-local", EnvironmentTestOptionLocal); +} + #endif // SKIP_ENVIRONMENT_TESTS } // anonymous namespace diff --git a/unittests/Support/ConstantRangeTest.cpp b/unittests/Support/ConstantRangeTest.cpp index 742bcb4..263f93c 100644 --- a/unittests/Support/ConstantRangeTest.cpp +++ b/unittests/Support/ConstantRangeTest.cpp @@ -114,11 +114,15 @@ TEST_F(ConstantRangeTest, SingleElement) { } TEST_F(ConstantRangeTest, GetSetSize) { - EXPECT_EQ(Full.getSetSize(), APInt(16, 0)); - EXPECT_EQ(Empty.getSetSize(), APInt(16, 0)); - EXPECT_EQ(One.getSetSize(), APInt(16, 1)); - EXPECT_EQ(Some.getSetSize(), APInt(16, 0xaa0)); - EXPECT_EQ(Wrap.getSetSize(), APInt(16, 0x10000 - 0xaa0)); + EXPECT_EQ(Full.getSetSize(), APInt(17, 65536)); + EXPECT_EQ(Empty.getSetSize(), APInt(17, 0)); + EXPECT_EQ(One.getSetSize(), APInt(17, 1)); + EXPECT_EQ(Some.getSetSize(), APInt(17, 0xaa0)); + + ConstantRange Wrap(APInt(4, 7), APInt(4, 3)); + ConstantRange Wrap2(APInt(4, 8), APInt(4, 7)); + EXPECT_EQ(Wrap.getSetSize(), APInt(5, 12)); + EXPECT_EQ(Wrap2.getSetSize(), APInt(5, 15)); } TEST_F(ConstantRangeTest, GetMinsAndMaxes) { @@ -189,6 +193,10 @@ TEST_F(ConstantRangeTest, ZExt) { EXPECT_EQ(ZSome, ConstantRange(Some.getLower().zext(20), Some.getUpper().zext(20))); EXPECT_EQ(ZWrap, ConstantRange(APInt(20, 0), APInt(20, 0x10000))); + + // zext([5, 0), 3->7) = [5, 8) + ConstantRange FiveZero(APInt(3, 5), APInt(3, 0)); + EXPECT_EQ(FiveZero.zeroExtend(7), ConstantRange(APInt(7, 5), APInt(7, 8))); } TEST_F(ConstantRangeTest, SExt) { @@ -232,6 +240,41 @@ TEST_F(ConstantRangeTest, IntersectWith) { ConstantRange LHS(APInt(16, 4), APInt(16, 2)); ConstantRange RHS(APInt(16, 6), APInt(16, 5)); EXPECT_TRUE(LHS.intersectWith(RHS) == LHS); + + // previous bug: intersection of [min, 3) and [2, max) should be 2 + LHS = ConstantRange(APInt(32, -2147483646), APInt(32, 3)); + RHS = ConstantRange(APInt(32, 2), APInt(32, 2147483646)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2))); + + // [2, 0) /\ [4, 3) = [2, 0) + LHS = ConstantRange(APInt(32, 2), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 4), APInt(32, 3)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2), APInt(32, 0))); + + // [2, 0) /\ [4, 2) = [4, 0) + LHS = ConstantRange(APInt(32, 2), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 4), APInt(32, 2)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 0))); + + // [4, 2) /\ [5, 1) = [5, 1) + LHS = ConstantRange(APInt(32, 4), APInt(32, 2)); + RHS = ConstantRange(APInt(32, 5), APInt(32, 1)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 5), APInt(32, 1))); + + // [2, 0) /\ [7, 4) = [7, 4) + LHS = ConstantRange(APInt(32, 2), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 7), APInt(32, 4)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 7), APInt(32, 4))); + + // [4, 2) /\ [1, 0) = [1, 0) + LHS = ConstantRange(APInt(32, 4), APInt(32, 2)); + RHS = ConstantRange(APInt(32, 1), APInt(32, 0)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 2))); + + // [15, 0) /\ [7, 6) = [15, 0) + LHS = ConstantRange(APInt(32, 15), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 7), APInt(32, 6)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0))); } TEST_F(ConstantRangeTest, UnionWith) { @@ -254,6 +297,23 @@ TEST_F(ConstantRangeTest, UnionWith) { ConstantRange(16)); } +TEST_F(ConstantRangeTest, SetDifference) { + EXPECT_EQ(Full.difference(Empty), Full); + EXPECT_EQ(Full.difference(Full), Empty); + EXPECT_EQ(Empty.difference(Empty), Empty); + EXPECT_EQ(Empty.difference(Full), Empty); + + ConstantRange A(APInt(16, 3), APInt(16, 7)); + ConstantRange B(APInt(16, 5), APInt(16, 9)); + ConstantRange C(APInt(16, 3), APInt(16, 5)); + ConstantRange D(APInt(16, 7), APInt(16, 9)); + ConstantRange E(APInt(16, 5), APInt(16, 4)); + ConstantRange F(APInt(16, 7), APInt(16, 3)); + EXPECT_EQ(A.difference(B), C); + EXPECT_EQ(B.difference(A), D); + EXPECT_EQ(E.difference(A), F); +} + TEST_F(ConstantRangeTest, SubtractAPInt) { EXPECT_EQ(Full.subtract(APInt(16, 4)), Full); EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty); @@ -326,6 +386,14 @@ TEST_F(ConstantRangeTest, Multiply) { EXPECT_EQ(Some.multiply(Wrap), Full); EXPECT_EQ(Wrap.multiply(Wrap), Full); + ConstantRange Zero(APInt(16, 0)); + EXPECT_EQ(Zero.multiply(Full), Zero); + EXPECT_EQ(Zero.multiply(Some), Zero); + EXPECT_EQ(Zero.multiply(Wrap), Zero); + EXPECT_EQ(Full.multiply(Zero), Zero); + EXPECT_EQ(Some.multiply(Zero), Zero); + EXPECT_EQ(Wrap.multiply(Zero), Zero); + // http://llvm.org/PR4545 EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply( ConstantRange(APInt(4, 6), APInt(4, 2))), diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp new file mode 100644 index 0000000..edd350a --- /dev/null +++ b/unittests/Support/FileOutputBufferTest.cpp @@ -0,0 +1,137 @@ +//===- llvm/unittest/Support/FileOutputBuffer.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 "llvm/ADT/OwningPtr.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/PathV2.h" +#include "llvm/Support/raw_ostream.h" + +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::sys; + +#define ASSERT_NO_ERROR(x) \ + if (error_code ASSERT_NO_ERROR_ec = x) { \ + errs() << #x ": did not return errc::success.\n" \ + << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \ + << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \ + } else {} + +namespace { + + +// NOTE: Temporarily run this test on unix only. Once the file mapping +// routines are ported to Windows, this conditional can be removed. +#if LLVM_ON_UNIX + + +TEST(FileOutputBuffer, Test) { + // Create unique temporary directory for these tests + SmallString<128> TestDirectory; + { + int fd; + ASSERT_NO_ERROR( + fs::unique_file("FileOutputBuffer-test-%%-%%-%%-%%/dir", fd, + TestDirectory)); + ::close(fd); + TestDirectory = path::parent_path(TestDirectory); + } + + // TEST 1: Verify commit case. + SmallString<128> File1(TestDirectory); + File1.append("/file1"); + { + OwningPtr<FileOutputBuffer> Buffer; + ASSERT_NO_ERROR(FileOutputBuffer::create(File1, 8192, Buffer)); + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Write to end of buffer to verify it is writable. + memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer. + ASSERT_NO_ERROR(Buffer->commit()); + } + // Verify file exists and starts with special header. + bool MagicMatches = false; + ASSERT_NO_ERROR(fs::has_magic(Twine(File1), Twine("AABBCCDDEEFFGGHHIIJJ"), + MagicMatches)); + EXPECT_TRUE(MagicMatches); + // Verify file is correct size. + uint64_t File1Size; + ASSERT_NO_ERROR(fs::file_size(Twine(File1), File1Size)); + ASSERT_EQ(File1Size, 8192ULL); + + // TEST 2: Verify abort case. + SmallString<128> File2(TestDirectory); + File2.append("/file2"); + { + OwningPtr<FileOutputBuffer> Buffer2; + ASSERT_NO_ERROR(FileOutputBuffer::create(File2, 8192, Buffer2)); + // Fill buffer with special header. + memcpy(Buffer2->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Do *not* commit buffer. + } + // Verify file does not exist (because buffer not commited). + bool Exists = false; + ASSERT_NO_ERROR(fs::exists(Twine(File2), Exists)); + EXPECT_FALSE(Exists); + + + // TEST 3: Verify sizing down case. + SmallString<128> File3(TestDirectory); + File3.append("/file3"); + { + OwningPtr<FileOutputBuffer> Buffer; + ASSERT_NO_ERROR(FileOutputBuffer::create(File3, 8192000, Buffer)); + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Write to end of buffer to verify it is writable. + memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer, but size down to smaller size + ASSERT_NO_ERROR(Buffer->commit(5000)); + } + // Verify file exists and starts with special header. + bool MagicMatches3 = false; + ASSERT_NO_ERROR(fs::has_magic(Twine(File3), Twine("AABBCCDDEEFFGGHHIIJJ"), + MagicMatches3)); + EXPECT_TRUE(MagicMatches3); + // Verify file is correct size. + uint64_t File3Size; + ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size)); + ASSERT_EQ(File3Size, 5000ULL); + + + // TEST 4: Verify file can be made executable. + SmallString<128> File4(TestDirectory); + File4.append("/file4"); + { + OwningPtr<FileOutputBuffer> Buffer; + ASSERT_NO_ERROR(FileOutputBuffer::create(File4, 8192, Buffer, + FileOutputBuffer::F_executable)); + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer. + ASSERT_NO_ERROR(Buffer->commit()); + } + // Verify file exists and is executable. + fs::file_status Status; + ASSERT_NO_ERROR(fs::status(Twine(File4), Status)); + bool IsExecutable = (Status.permissions() & fs::owner_exe); + EXPECT_TRUE(IsExecutable); + + // Clean up. + uint32_t RemovedCount; + ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), RemovedCount)); +} + +#endif // LLVM_ON_UNIX + +} // anonymous namespace diff --git a/unittests/Support/IntegersSubsetTest.cpp b/unittests/Support/IntegersSubsetTest.cpp new file mode 100644 index 0000000..5d1dde4 --- /dev/null +++ b/unittests/Support/IntegersSubsetTest.cpp @@ -0,0 +1,328 @@ +//===- llvm/unittest/Support/IntegersSubsetTest.cpp - IntegersSubset tests ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/APInt.h" +#include "llvm/Support/IntegersSubset.h" +#include "llvm/Support/IntegersSubsetMapping.h" + +#include "gtest/gtest.h" + +#include <vector> + +using namespace llvm; + +namespace { + + class Int : public APInt { + public: + Int() {} + Int(uint64_t V) : APInt(64, V) {} + Int(const APInt& Src) : APInt(Src) {} + bool operator < (const APInt& RHS) const { return ult(RHS); } + bool operator > (const APInt& RHS) const { return ugt(RHS); } + bool operator <= (const APInt& RHS) const { return ule(RHS); } + bool operator >= (const APInt& RHS) const { return uge(RHS); } + }; + + typedef IntRange<Int> Range; + typedef IntegersSubsetGeneric<Int> Subset; + typedef IntegersSubsetMapping<unsigned,Subset,Int> Mapping; + + TEST(IntegersSubsetTest, GeneralTest) { + + // Test construction. + + std::vector<Range> Ranges; + Ranges.reserve(3); + + // Initialize Subset as union of three pairs: + // { {0, 8}, {10, 18}, {20, 28} } + for (unsigned i = 0; i < 3; ++i) + Ranges.push_back(Range(Int(i*10), Int(i*10 + 8))); + + Subset TheSubset(Ranges); + + for (unsigned i = 0; i < 3; ++i) { + EXPECT_EQ(TheSubset.getItem(i).getLow(), Int(i*10)); + EXPECT_EQ(TheSubset.getItem(i).getHigh(), Int(i*10 + 8)); + } + + EXPECT_EQ(TheSubset.getNumItems(), 3ULL); + + // Test belonging to range. + + EXPECT_TRUE(TheSubset.isSatisfies(Int(5))); + EXPECT_FALSE(TheSubset.isSatisfies(Int(9))); + + // Test when subset contains the only item. + + Ranges.clear(); + Ranges.push_back(Range(Int(10), Int(10))); + + Subset TheSingleNumber(Ranges); + + EXPECT_TRUE(TheSingleNumber.isSingleNumber()); + + Ranges.push_back(Range(Int(12), Int(15))); + + Subset NotASingleNumber(Ranges); + + EXPECT_FALSE(NotASingleNumber.isSingleNumber()); + + // Test when subset contains items that are not a ranges but + // the single numbers. + + Ranges.clear(); + Ranges.push_back(Range(Int(10), Int(10))); + Ranges.push_back(Range(Int(15), Int(19))); + + Subset WithSingleNumberItems(Ranges); + + EXPECT_TRUE(WithSingleNumberItems.isSingleNumber(0)); + EXPECT_FALSE(WithSingleNumberItems.isSingleNumber(1)); + + // Test size of subset. Note subset itself may be not optimized (improper), + // so it may contain duplicates, and the size of subset { {0, 9} {5, 9} } + // will 15 instead of 10. + + Ranges.clear(); + Ranges.push_back(Range(Int(0), Int(9))); + Ranges.push_back(Range(Int(5), Int(9))); + + Subset NotOptimizedSubset(Ranges); + + EXPECT_EQ(NotOptimizedSubset.getSize(), 15ULL); + + // Test access to a single value. + // getSingleValue(idx) method represents subset as flat numbers collection, + // so subset { {0, 3}, {8, 10} } will represented as array + // { 0, 1, 2, 3, 8, 9, 10 }. + + Ranges.clear(); + Ranges.push_back(Range(Int(0), Int(3))); + Ranges.push_back(Range(Int(8), Int(10))); + + Subset OneMoreSubset(Ranges); + + EXPECT_EQ(OneMoreSubset.getSingleValue(5), Int(9)); + } + + TEST(IntegersSubsetTest, MappingTest) { + + Mapping::Cases TheCases; + + unsigned Successors[3] = {0, 1, 2}; + + // Test construction. + + Mapping TheMapping; + for (unsigned i = 0; i < 3; ++i) + TheMapping.add(Int(10*i), Int(10*i + 9), Successors + i); + TheMapping.add(Int(111), Int(222), Successors); + TheMapping.removeItem(--TheMapping.end()); + + TheMapping.getCases(TheCases); + + EXPECT_EQ(TheCases.size(), 3ULL); + + for (unsigned i = 0; i < 3; ++i) { + Mapping::Cases::iterator CaseIt = TheCases.begin(); + std::advance(CaseIt, i); + EXPECT_EQ(CaseIt->first, Successors + i); + EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL); + EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(10*i), Int(10*i + 9))); + } + + // Test verification. + + Mapping ImproperMapping; + ImproperMapping.add(Int(10), Int(11), Successors + 0); + ImproperMapping.add(Int(11), Int(12), Successors + 1); + + Mapping::RangeIterator ErrItem; + EXPECT_FALSE(ImproperMapping.verify(ErrItem)); + EXPECT_EQ(ErrItem, --ImproperMapping.end()); + + Mapping ProperMapping; + ProperMapping.add(Int(10), Int(11), Successors + 0); + ProperMapping.add(Int(12), Int(13), Successors + 1); + + EXPECT_TRUE(ProperMapping.verify(ErrItem)); + + // Test optimization. + + Mapping ToBeOptimized; + + for (unsigned i = 0; i < 3; ++i) { + ToBeOptimized.add(Int(i * 10), Int(i * 10 + 1), Successors + i); + ToBeOptimized.add(Int(i * 10 + 2), Int(i * 10 + 9), Successors + i); + } + + ToBeOptimized.optimize(); + + TheCases.clear(); + ToBeOptimized.getCases(TheCases); + + EXPECT_EQ(TheCases.size(), 3ULL); + + for (unsigned i = 0; i < 3; ++i) { + Mapping::Cases::iterator CaseIt = TheCases.begin(); + std::advance(CaseIt, i); + EXPECT_EQ(CaseIt->first, Successors + i); + EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL); + EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(i * 10), Int(i * 10 + 9))); + } + } + + typedef unsigned unsigned_pair[2]; + typedef unsigned_pair unsigned_ranges[]; + + void TestDiff( + const unsigned_ranges LHS, + unsigned LSize, + const unsigned_ranges RHS, + unsigned RSize, + const unsigned_ranges ExcludeRes, + unsigned ExcludeResSize, + const unsigned_ranges IntersectRes, + unsigned IntersectResSize + ) { + + Mapping::RangesCollection Ranges; + + Mapping LHSMapping; + for (unsigned i = 0; i < LSize; ++i) + Ranges.push_back(Range(Int(LHS[i][0]), Int(LHS[i][1]))); + LHSMapping.add(Ranges); + + Ranges.clear(); + + Mapping RHSMapping; + for (unsigned i = 0; i < RSize; ++i) + Ranges.push_back(Range(Int(RHS[i][0]), Int(RHS[i][1]))); + RHSMapping.add(Ranges); + + Mapping LExclude, Intersection; + + LHSMapping.diff(&LExclude, &Intersection, 0, RHSMapping); + + if (ExcludeResSize) { + EXPECT_EQ(LExclude.size(), ExcludeResSize); + + unsigned i = 0; + for (Mapping::RangeIterator rei = LExclude.begin(), + e = LExclude.end(); rei != e; ++rei, ++i) + EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1])); + } else + EXPECT_TRUE(LExclude.empty()); + + if (IntersectResSize) { + EXPECT_EQ(Intersection.size(), IntersectResSize); + + unsigned i = 0; + for (Mapping::RangeIterator ii = Intersection.begin(), + e = Intersection.end(); ii != e; ++ii, ++i) + EXPECT_EQ(ii->first, Range(IntersectRes[i][0], IntersectRes[i][1])); + } else + EXPECT_TRUE(Intersection.empty()); + + LExclude.clear(); + Intersection.clear(); + RHSMapping.diff(0, &Intersection, &LExclude, LHSMapping); + + // Check LExclude again. + if (ExcludeResSize) { + EXPECT_EQ(LExclude.size(), ExcludeResSize); + + unsigned i = 0; + for (Mapping::RangeIterator rei = LExclude.begin(), + e = LExclude.end(); rei != e; ++rei, ++i) + EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1])); + } else + EXPECT_TRUE(LExclude.empty()); + } + + TEST(IntegersSubsetTest, DiffTest) { + + static const unsigned NOT_A_NUMBER = 0xffff; + + { + unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } }; + unsigned_ranges RHS = { { 3, 14 } }; + unsigned_ranges ExcludeRes = { { 0, 2 }, { 15, 17 } }; + unsigned_ranges IntersectRes = { { 3, 4 }, { 7, 10 }, { 13, 14 } }; + + TestDiff(LHS, 3, RHS, 1, ExcludeRes, 2, IntersectRes, 3); + } + + { + unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } }; + unsigned_ranges RHS = { { 0, 4 }, { 13, 17 } }; + unsigned_ranges ExcludeRes = { { 7, 10 } }; + unsigned_ranges IntersectRes = { { 0, 4 }, { 13, 17 } }; + + TestDiff(LHS, 3, RHS, 2, ExcludeRes, 1, IntersectRes, 2); + } + + { + unsigned_ranges LHS = { { 0, 17 } }; + unsigned_ranges RHS = { { 1, 5 }, { 10, 12 }, { 15, 16 } }; + unsigned_ranges ExcludeRes = + { { 0, 0 }, { 6, 9 }, { 13, 14 }, { 17, 17 } }; + unsigned_ranges IntersectRes = { { 1, 5 }, { 10, 12 }, { 15, 16 } }; + + TestDiff(LHS, 1, RHS, 3, ExcludeRes, 4, IntersectRes, 3); + } + + { + unsigned_ranges LHS = { { 2, 4 } }; + unsigned_ranges RHS = { { 0, 5 } }; + unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} }; + unsigned_ranges IntersectRes = { { 2, 4 } }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 0, IntersectRes, 1); + } + + { + unsigned_ranges LHS = { { 2, 4 } }; + unsigned_ranges RHS = { { 7, 8 } }; + unsigned_ranges ExcludeRes = { { 2, 4 } }; + unsigned_ranges IntersectRes = { {NOT_A_NUMBER, NOT_A_NUMBER} }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0); + } + + { + unsigned_ranges LHS = { { 3, 7 } }; + unsigned_ranges RHS = { { 1, 4 } }; + unsigned_ranges ExcludeRes = { { 5, 7 } }; + unsigned_ranges IntersectRes = { { 3, 4 } }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 1); + } + + { + unsigned_ranges LHS = { { 0, 7 } }; + unsigned_ranges RHS = { { 0, 5 }, { 6, 9 } }; + unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} }; + unsigned_ranges IntersectRes = { { 0, 5 }, {6, 7} }; + + TestDiff(LHS, 1, RHS, 2, ExcludeRes, 0, IntersectRes, 2); + } + + { + unsigned_ranges LHS = { { 17, 17 } }; + unsigned_ranges RHS = { { 4, 4 } }; + unsigned_ranges ExcludeRes = { {17, 17} }; + unsigned_ranges IntersectRes = { { NOT_A_NUMBER, NOT_A_NUMBER } }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0); + } + } +} diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index 358dad0..a071a5a 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -312,4 +312,72 @@ TEST_F(FileSystemTest, Magic) { } } +#if !defined(_WIN32) // FIXME: Win32 has different permission schema. +TEST_F(FileSystemTest, Permissions) { + // Create a temp file. + int FileDescriptor; + SmallString<64> TempPath; + ASSERT_NO_ERROR( + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath)); + + // Mark file as read-only + const fs::perms AllWrite = fs::owner_write|fs::group_write|fs::others_write; + ASSERT_NO_ERROR(fs::permissions(Twine(TempPath), fs::remove_perms|AllWrite)); + + // Verify file is read-only + fs::file_status Status; + ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status)); + bool AnyWriteBits = (Status.permissions() & AllWrite); + EXPECT_FALSE(AnyWriteBits); + + // Mark file as read-write + ASSERT_NO_ERROR(fs::permissions(Twine(TempPath), fs::add_perms|AllWrite)); + + // Verify file is read-write + ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status)); + AnyWriteBits = (Status.permissions() & AllWrite); + EXPECT_TRUE(AnyWriteBits); +} +#endif + +#if !defined(_WIN32) // FIXME: temporary suppressed. +TEST_F(FileSystemTest, FileMapping) { + // Create a temp file. + int FileDescriptor; + SmallString<64> TempPath; + ASSERT_NO_ERROR( + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath)); + + // Grow temp file to be 4096 bytes + ASSERT_NO_ERROR(sys::fs::resize_file(Twine(TempPath), 4096)); + + // Map in temp file and add some content + void* MappedMemory; + ASSERT_NO_ERROR(fs::map_file_pages(Twine(TempPath), 0, 4096, + true /*writable*/, MappedMemory)); + char* Memory = reinterpret_cast<char*>(MappedMemory); + strcpy(Memory, "hello there"); + + // Unmap temp file + ASSERT_NO_ERROR(fs::unmap_file_pages(MappedMemory, 4096)); + MappedMemory = NULL; + Memory = NULL; + + // Map it back in read-only + ASSERT_NO_ERROR(fs::map_file_pages(Twine(TempPath), 0, 4096, + false /*read-only*/, MappedMemory)); + + // Verify content + Memory = reinterpret_cast<char*>(MappedMemory); + bool SAME = (strcmp(Memory, "hello there") == 0); + EXPECT_TRUE(SAME); + + // Unmap temp file + ASSERT_NO_ERROR(fs::unmap_file_pages(MappedMemory, 4096)); + MappedMemory = NULL; + Memory = NULL; +} +#endif + + } // anonymous namespace diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp index e88427a..480a573 100644 --- a/unittests/Support/YAMLParserTest.cpp +++ b/unittests/Support/YAMLParserTest.cpp @@ -16,11 +16,17 @@ namespace llvm { +static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) { + // Prevent SourceMgr from writing errors to stderr + // to reduce noise in unit test runs. +} + // Checks that the given input gives a parse error. Makes sure that an error // text is available and the parse fails. static void ExpectParseError(StringRef Message, StringRef Input) { SourceMgr SM; yaml::Stream Stream(Input, SM); + SM.setDiagHandler(SuppressDiagnosticsOutput); EXPECT_FALSE(Stream.validate()) << Message << ": " << Input; EXPECT_TRUE(Stream.failed()) << Message << ": " << Input; } diff --git a/unittests/Transforms/CMakeLists.txt b/unittests/Transforms/CMakeLists.txt new file mode 100644 index 0000000..e3ce185 --- /dev/null +++ b/unittests/Transforms/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(Utils) diff --git a/unittests/Transforms/Utils/CMakeLists.txt b/unittests/Transforms/Utils/CMakeLists.txt new file mode 100644 index 0000000..365bfbb --- /dev/null +++ b/unittests/Transforms/Utils/CMakeLists.txt @@ -0,0 +1,8 @@ +set(LLVM_LINK_COMPONENTS + TransformUtils + ) + +add_llvm_unittest(UtilsTests + Cloning.cpp + Local.cpp + ) diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp index 4243b2d..ea3d5be 100644 --- a/unittests/Transforms/Utils/Cloning.cpp +++ b/unittests/Transforms/Utils/Cloning.cpp @@ -18,6 +18,7 @@ using namespace llvm; namespace { + class CloneInstruction : public ::testing::Test { protected: virtual void SetUp() { @@ -48,7 +49,6 @@ protected: LLVMContext context; Value *V; }; -} TEST_F(CloneInstruction, OverflowBits) { V = new Argument(Type::getInt32Ty(context)); @@ -142,3 +142,5 @@ TEST_F(CloneInstruction, Exact) { SDiv->setIsExact(true); EXPECT_TRUE(this->clone(SDiv)->isExact()); } + +} diff --git a/unittests/Transforms/Utils/Local.cpp b/unittests/Transforms/Utils/Local.cpp index 3026b4b..727f5ea 100644 --- a/unittests/Transforms/Utils/Local.cpp +++ b/unittests/Transforms/Utils/Local.cpp @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" #include "llvm/BasicBlock.h" +#include "llvm/IRBuilder.h" #include "llvm/Instructions.h" #include "llvm/LLVMContext.h" -#include "llvm/Support/IRBuilder.h" #include "llvm/Transforms/Utils/Local.h" +#include "gtest/gtest.h" + using namespace llvm; TEST(Local, RecursivelyDeleteDeadPHINodes) { diff --git a/unittests/Transforms/Utils/Makefile b/unittests/Transforms/Utils/Makefile index fdf4be0..e6c2a2c 100644 --- a/unittests/Transforms/Utils/Makefile +++ b/unittests/Transforms/Utils/Makefile @@ -9,7 +9,7 @@ LEVEL = ../../.. TESTNAME = Utils -LINK_COMPONENTS := core support transformutils +LINK_COMPONENTS := TransformUtils include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/VMCore/CMakeLists.txt b/unittests/VMCore/CMakeLists.txt new file mode 100644 index 0000000..4025c7a --- /dev/null +++ b/unittests/VMCore/CMakeLists.txt @@ -0,0 +1,35 @@ +set(LLVM_LINK_COMPONENTS + asmparser + core + ipa + ) + +set(VMCoreSources + ConstantsTest.cpp + DominatorTreeTest.cpp + IRBuilderTest.cpp + InstructionsTest.cpp + MDBuilderTest.cpp + MetadataTest.cpp + PassManagerTest.cpp + TypeBuilderTest.cpp + TypesTest.cpp + ValueMapTest.cpp + VerifierTest.cpp + ) + +# MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug. +# See issue#331418 in Visual Studio. +if(MSVC AND MSVC_VERSION LESS 1600) + list(REMOVE_ITEM VMCoreSources ValueMapTest.cpp) +endif() + +# HACK: Declare a couple of source files as optionally compiled to satisfy the +# missing-file-checker in LLVM's weird CMake build. +set(LLVM_OPTIONAL_SOURCES + ValueMapTest.cpp + ) + +add_llvm_unittest(VMCoreTests + ${VMCoreSources} + ) diff --git a/unittests/Support/IRBuilderTest.cpp b/unittests/VMCore/IRBuilderTest.cpp index b15de9e..b6a3795 100644 --- a/unittests/Support/IRBuilderTest.cpp +++ b/unittests/VMCore/IRBuilderTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/Support/IRBuilderTest.cpp - IRBuilder tests ----------===// +//===- llvm/unittest/VMCore/IRBuilderTest.cpp - IRBuilder tests -----------===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/IRBuilder.h" #include "llvm/BasicBlock.h" #include "llvm/Function.h" +#include "llvm/IRBuilder.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" +#include "llvm/MDBuilder.h" #include "llvm/Module.h" #include "llvm/ADT/OwningPtr.h" @@ -20,13 +21,14 @@ using namespace llvm; namespace { + class IRBuilderTest : public testing::Test { protected: virtual void SetUp() { M.reset(new Module("MyModule", getGlobalContext())); FunctionType *FTy = FunctionType::get(Type::getVoidTy(getGlobalContext()), /*isVarArg=*/false); - Function *F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); + F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); BB = BasicBlock::Create(getGlobalContext(), "", F); } @@ -36,9 +38,9 @@ protected: } OwningPtr<Module> M; + Function *F; BasicBlock *BB; }; -} TEST_F(IRBuilderTest, Lifetime) { IRBuilder<> Builder(BB); @@ -70,3 +72,28 @@ TEST_F(IRBuilderTest, Lifetime) { ASSERT_TRUE(II_End1 != NULL); EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end); } + +TEST_F(IRBuilderTest, CreateCondBr) { + IRBuilder<> Builder(BB); + BasicBlock *TBB = BasicBlock::Create(getGlobalContext(), "", F); + BasicBlock *FBB = BasicBlock::Create(getGlobalContext(), "", F); + + BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB); + TerminatorInst *TI = BB->getTerminator(); + EXPECT_EQ(BI, TI); + EXPECT_EQ(2u, TI->getNumSuccessors()); + EXPECT_EQ(TBB, TI->getSuccessor(0)); + EXPECT_EQ(FBB, TI->getSuccessor(1)); + + BI->eraseFromParent(); + MDNode *Weights = MDBuilder(getGlobalContext()).createBranchWeights(42, 13); + BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights); + TI = BB->getTerminator(); + EXPECT_EQ(BI, TI); + EXPECT_EQ(2u, TI->getNumSuccessors()); + EXPECT_EQ(TBB, TI->getSuccessor(0)); + EXPECT_EQ(FBB, TI->getSuccessor(1)); + EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof)); +} + +} diff --git a/unittests/VMCore/InstructionsTest.cpp b/unittests/VMCore/InstructionsTest.cpp index d002101..72cdc8b 100644 --- a/unittests/VMCore/InstructionsTest.cpp +++ b/unittests/VMCore/InstructionsTest.cpp @@ -7,16 +7,16 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Instructions.h" #include "llvm/BasicBlock.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/IRBuilder.h" +#include "llvm/Instructions.h" #include "llvm/LLVMContext.h" +#include "llvm/MDBuilder.h" #include "llvm/Operator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/Support/MDBuilder.h" -#include "llvm/Support/IRBuilder.h" #include "llvm/Target/TargetData.h" #include "gtest/gtest.h" diff --git a/unittests/Support/MDBuilderTest.cpp b/unittests/VMCore/MDBuilderTest.cpp index d54c7e8..847039b 100644 --- a/unittests/Support/MDBuilderTest.cpp +++ b/unittests/VMCore/MDBuilderTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittests/Support/MDBuilderTest.cpp - MDBuilder unit tests ----===// +//===- llvm/unittests/MDBuilderTest.cpp - MDBuilder unit tests ------------===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" +#include "llvm/IRBuilder.h" +#include "llvm/MDBuilder.h" #include "llvm/Operator.h" -#include "llvm/Support/IRBuilder.h" -#include "llvm/Support/MDBuilder.h" + +#include "gtest/gtest.h" + using namespace llvm; namespace { diff --git a/unittests/VMCore/Makefile b/unittests/VMCore/Makefile index df55065..d743dc5 100644 --- a/unittests/VMCore/Makefile +++ b/unittests/VMCore/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. TESTNAME = VMCore -LINK_COMPONENTS := core support target ipa asmparser +LINK_COMPONENTS := core ipa asmparser include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/VMCore/PassManagerTest.cpp index af845b0..60d33c1 100644 --- a/unittests/VMCore/PassManagerTest.cpp +++ b/unittests/VMCore/PassManagerTest.cpp @@ -324,7 +324,7 @@ namespace llvm { Passes.run(M); // Some passes must be rerun because a pass that modified the - // module/function was run inbetween + // module/function was run in between EXPECT_EQ(2, mNDM->run); EXPECT_EQ(1, mNDNM->run); EXPECT_EQ(1, mNDM2->run); diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/VMCore/TypeBuilderTest.cpp index 20d0e73..a746b1f 100644 --- a/unittests/Support/TypeBuilderTest.cpp +++ b/unittests/VMCore/TypeBuilderTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/Support/TypeBuilderTest.cpp - TypeBuilder tests -----===// +//===- llvm/unittest/TypeBuilderTest.cpp - TypeBuilder tests --------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/TypeBuilder.h" +#include "llvm/TypeBuilder.h" #include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" @@ -167,13 +167,13 @@ TEST(TypeBuilderTest, Context) { &(TypeBuilder<types::i<1>, true>::get(context2))->getContext()); } -class MyType { +struct MyType { int a; int *b; void *array[1]; }; -class MyPortableType { +struct MyPortableType { int32_t a; int32_t *b; void *array[1]; diff --git a/unittests/VMCore/TypesTest.cpp b/unittests/VMCore/TypesTest.cpp new file mode 100644 index 0000000..0416643 --- /dev/null +++ b/unittests/VMCore/TypesTest.cpp @@ -0,0 +1,30 @@ +//===- llvm/unittest/VMCore/TypesTest.cpp - Type unit tests ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(TypesTest, StructType) { + LLVMContext C; + + // PR13522 + StructType *Struct = StructType::create(C, "FooBar"); + EXPECT_EQ("FooBar", Struct->getName()); + Struct->setName(Struct->getName().substr(0, 3)); + EXPECT_EQ("Foo", Struct->getName()); + Struct->setName(""); + EXPECT_TRUE(Struct->getName().empty()); + EXPECT_FALSE(Struct->hasName()); +} + +} // end anonymous namespace |