summaryrefslogtreecommitdiffstats
path: root/unittests/Support
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Support')
-rw-r--r--unittests/Support/AllocatorTest.cpp143
-rw-r--r--unittests/Support/CommandLineTest.cpp60
-rw-r--r--unittests/Support/ConstantRangeTest.cpp351
-rw-r--r--unittests/Support/MathExtrasTest.cpp2
-rw-r--r--unittests/Support/RegexTest.cpp65
-rw-r--r--unittests/Support/TypeBuilderTest.cpp281
-rw-r--r--unittests/Support/ValueHandleTest.cpp118
-rw-r--r--unittests/Support/raw_ostream_test.cpp45
8 files changed, 918 insertions, 147 deletions
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
new file mode 100644
index 0000000..2a01f3a
--- /dev/null
+++ b/unittests/Support/AllocatorTest.cpp
@@ -0,0 +1,143 @@
+//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator 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/Allocator.h"
+
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+using namespace llvm;
+
+namespace {
+
+TEST(AllocatorTest, Basics) {
+ BumpPtrAllocator Alloc;
+ int *a = (int*)Alloc.Allocate(sizeof(int), 0);
+ int *b = (int*)Alloc.Allocate(sizeof(int) * 10, 0);
+ int *c = (int*)Alloc.Allocate(sizeof(int), 0);
+ *a = 1;
+ b[0] = 2;
+ b[9] = 2;
+ *c = 3;
+ EXPECT_EQ(1, *a);
+ EXPECT_EQ(2, b[0]);
+ EXPECT_EQ(2, b[9]);
+ EXPECT_EQ(3, *c);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+}
+
+// Allocate enough bytes to create three slabs.
+TEST(AllocatorTest, ThreeSlabs) {
+ BumpPtrAllocator Alloc(4096, 4096);
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(3U, Alloc.GetNumSlabs());
+}
+
+// Allocate enough bytes to create two slabs, reset the allocator, and do it
+// again.
+TEST(AllocatorTest, TestReset) {
+ BumpPtrAllocator Alloc(4096, 4096);
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+ Alloc.Reset();
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Test some allocations at varying alignments.
+TEST(AllocatorTest, TestAlignment) {
+ BumpPtrAllocator Alloc;
+ uintptr_t a;
+ a = (uintptr_t)Alloc.Allocate(1, 2);
+ EXPECT_EQ(0U, a & 1);
+ a = (uintptr_t)Alloc.Allocate(1, 4);
+ EXPECT_EQ(0U, a & 3);
+ a = (uintptr_t)Alloc.Allocate(1, 8);
+ EXPECT_EQ(0U, a & 7);
+ a = (uintptr_t)Alloc.Allocate(1, 16);
+ EXPECT_EQ(0U, a & 15);
+ a = (uintptr_t)Alloc.Allocate(1, 32);
+ EXPECT_EQ(0U, a & 31);
+ a = (uintptr_t)Alloc.Allocate(1, 64);
+ EXPECT_EQ(0U, a & 63);
+ a = (uintptr_t)Alloc.Allocate(1, 128);
+ EXPECT_EQ(0U, a & 127);
+}
+
+// Test allocating just over the slab size. This tests a bug where before the
+// allocator incorrectly calculated the buffer end pointer.
+TEST(AllocatorTest, TestOverflow) {
+ BumpPtrAllocator Alloc(4096, 4096);
+
+ // Fill the slab right up until the end pointer.
+ Alloc.Allocate(4096 - sizeof(MemSlab), 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+
+ // If we dont't allocate a new slab, then we will have overflowed.
+ Alloc.Allocate(1, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Mock slab allocator that returns slabs aligned on 4096 bytes. There is no
+// easy portable way to do this, so this is kind of a hack.
+class MockSlabAllocator : public SlabAllocator {
+ MemSlab *LastSlab;
+
+public:
+ virtual ~MockSlabAllocator() { }
+
+ virtual MemSlab *Allocate(size_t Size) {
+ // Allocate space for the alignment, the slab, and a void* that goes right
+ // before the slab.
+ size_t Alignment = 4096;
+ void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));
+
+ // Make the slab.
+ MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase+sizeof(void*)+Alignment-1) &
+ ~(uintptr_t)(Alignment - 1));
+ Slab->Size = Size;
+ Slab->NextPtr = 0;
+
+ // Hold a pointer to the base so we can free the whole malloced block.
+ ((void**)Slab)[-1] = MemBase;
+
+ LastSlab = Slab;
+ return Slab;
+ }
+
+ virtual void Deallocate(MemSlab *Slab) {
+ free(((void**)Slab)[-1]);
+ }
+
+ MemSlab *GetLastSlab() {
+ return LastSlab;
+ }
+};
+
+// Allocate a large-ish block with a really large alignment so that the
+// allocator will think that it has space, but after it does the alignment it
+// will not.
+TEST(AllocatorTest, TestBigAlignment) {
+ MockSlabAllocator SlabAlloc;
+ BumpPtrAllocator Alloc(4096, 4096, SlabAlloc);
+ uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048);
+ MemSlab *Slab = SlabAlloc.GetLastSlab();
+ EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
new file mode 100644
index 0000000..72fa24a
--- /dev/null
+++ b/unittests/Support/CommandLineTest.cpp
@@ -0,0 +1,60 @@
+//===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine 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/CommandLine.h"
+#include "llvm/Config/config.h"
+
+#include "gtest/gtest.h"
+
+#include <string>
+#include <stdlib.h>
+
+using namespace llvm;
+
+namespace {
+
+class TempEnvVar {
+ public:
+ TempEnvVar(const char *name, const char *value)
+ : name(name) {
+ const char *old_value = getenv(name);
+ EXPECT_EQ(NULL, old_value) << old_value;
+#if HAVE_SETENV
+ setenv(name, value, true);
+#else
+# define SKIP_ENVIRONMENT_TESTS
+#endif
+ }
+
+ ~TempEnvVar() {
+#if HAVE_SETENV
+ // Assume setenv and unsetenv come together.
+ unsetenv(name);
+#endif
+ }
+
+ private:
+ const char *const name;
+};
+
+#ifndef SKIP_ENVIRONMENT_TESTS
+
+const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS";
+
+cl::opt<std::string> EnvironmentTestOption("env-test-opt");
+TEST(CommandLineTest, ParseEnvironment) {
+ TempEnvVar TEV(test_env_var, "-env-test-opt=hello");
+ EXPECT_EQ("", EnvironmentTestOption);
+ cl::ParseEnvironmentOptions("CommandLineTest", test_env_var);
+ EXPECT_EQ("hello", EnvironmentTestOption);
+}
+
+#endif // SKIP_ENVIRONMENT_TESTS
+
+} // anonymous namespace
diff --git a/unittests/Support/ConstantRangeTest.cpp b/unittests/Support/ConstantRangeTest.cpp
new file mode 100644
index 0000000..6b8d01d
--- /dev/null
+++ b/unittests/Support/ConstantRangeTest.cpp
@@ -0,0 +1,351 @@
+//===- llvm/unittest/Support/ConstantRangeTest.cpp - ConstantRange 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/ConstantRange.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class ConstantRangeTest : public ::testing::Test {
+protected:
+ static ConstantRange Full;
+ static ConstantRange Empty;
+ static ConstantRange One;
+ static ConstantRange Some;
+ static ConstantRange Wrap;
+};
+
+ConstantRange ConstantRangeTest::Full(16);
+ConstantRange ConstantRangeTest::Empty(16, false);
+ConstantRange ConstantRangeTest::One(APInt(16, 0xa));
+ConstantRange ConstantRangeTest::Some(APInt(16, 0xa), APInt(16, 0xaaa));
+ConstantRange ConstantRangeTest::Wrap(APInt(16, 0xaaa), APInt(16, 0xa));
+
+TEST_F(ConstantRangeTest, Basics) {
+ EXPECT_TRUE(Full.isFullSet());
+ EXPECT_FALSE(Full.isEmptySet());
+ EXPECT_FALSE(Full.isWrappedSet());
+ EXPECT_TRUE(Full.contains(APInt(16, 0x0)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0x9)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0xa)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0xaa9)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(Empty.isFullSet());
+ EXPECT_TRUE(Empty.isEmptySet());
+ EXPECT_FALSE(Empty.isWrappedSet());
+ EXPECT_FALSE(Empty.contains(APInt(16, 0x0)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0x9)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0xa)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0xaa9)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(One.isFullSet());
+ EXPECT_FALSE(One.isEmptySet());
+ EXPECT_FALSE(One.isWrappedSet());
+ EXPECT_FALSE(One.contains(APInt(16, 0x0)));
+ EXPECT_FALSE(One.contains(APInt(16, 0x9)));
+ EXPECT_TRUE(One.contains(APInt(16, 0xa)));
+ EXPECT_FALSE(One.contains(APInt(16, 0xaa9)));
+ EXPECT_FALSE(One.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(Some.isFullSet());
+ EXPECT_FALSE(Some.isEmptySet());
+ EXPECT_FALSE(Some.isWrappedSet());
+ EXPECT_FALSE(Some.contains(APInt(16, 0x0)));
+ EXPECT_FALSE(Some.contains(APInt(16, 0x9)));
+ EXPECT_TRUE(Some.contains(APInt(16, 0xa)));
+ EXPECT_TRUE(Some.contains(APInt(16, 0xaa9)));
+ EXPECT_FALSE(Some.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(Wrap.isFullSet());
+ EXPECT_FALSE(Wrap.isEmptySet());
+ EXPECT_TRUE(Wrap.isWrappedSet());
+ EXPECT_TRUE(Wrap.contains(APInt(16, 0x0)));
+ EXPECT_TRUE(Wrap.contains(APInt(16, 0x9)));
+ EXPECT_FALSE(Wrap.contains(APInt(16, 0xa)));
+ EXPECT_FALSE(Wrap.contains(APInt(16, 0xaa9)));
+ EXPECT_TRUE(Wrap.contains(APInt(16, 0xaaa)));
+}
+
+TEST_F(ConstantRangeTest, Equality) {
+ EXPECT_EQ(Full, Full);
+ EXPECT_EQ(Empty, Empty);
+ EXPECT_EQ(One, One);
+ EXPECT_EQ(Some, Some);
+ EXPECT_EQ(Wrap, Wrap);
+ EXPECT_NE(Full, Empty);
+ EXPECT_NE(Full, One);
+ EXPECT_NE(Full, Some);
+ EXPECT_NE(Full, Wrap);
+ EXPECT_NE(Empty, One);
+ EXPECT_NE(Empty, Some);
+ EXPECT_NE(Empty, Wrap);
+ EXPECT_NE(One, Some);
+ EXPECT_NE(One, Wrap);
+ EXPECT_NE(Some, Wrap);
+}
+
+TEST_F(ConstantRangeTest, SingleElement) {
+ EXPECT_EQ(Full.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(Empty.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(*One.getSingleElement(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(Wrap.getSingleElement(), static_cast<APInt *>(NULL));
+
+ EXPECT_FALSE(Full.isSingleElement());
+ EXPECT_FALSE(Empty.isSingleElement());
+ EXPECT_TRUE(One.isSingleElement());
+ EXPECT_FALSE(Some.isSingleElement());
+ EXPECT_FALSE(Wrap.isSingleElement());
+}
+
+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));
+}
+
+TEST_F(ConstantRangeTest, GetMinsAndMaxes) {
+ EXPECT_EQ(Full.getUnsignedMax(), APInt(16, UINT16_MAX));
+ EXPECT_EQ(One.getUnsignedMax(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getUnsignedMax(), APInt(16, 0xaa9));
+ EXPECT_EQ(Wrap.getUnsignedMax(), APInt(16, UINT16_MAX));
+
+ EXPECT_EQ(Full.getUnsignedMin(), APInt(16, 0));
+ EXPECT_EQ(One.getUnsignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getUnsignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Wrap.getUnsignedMin(), APInt(16, 0));
+
+ EXPECT_EQ(Full.getSignedMax(), APInt(16, INT16_MAX));
+ EXPECT_EQ(One.getSignedMax(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getSignedMax(), APInt(16, 0xaa9));
+ EXPECT_EQ(Wrap.getSignedMax(), APInt(16, INT16_MAX));
+
+ EXPECT_EQ(Full.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));
+ EXPECT_EQ(One.getSignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getSignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Wrap.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));
+
+ // Found by Klee
+ EXPECT_EQ(ConstantRange(APInt(4, 7), APInt(4, 0)).getSignedMax(),
+ APInt(4, 7));
+}
+
+TEST_F(ConstantRangeTest, Trunc) {
+ ConstantRange TFull = Full.truncate(10);
+ ConstantRange TEmpty = Empty.truncate(10);
+ ConstantRange TOne = One.truncate(10);
+ ConstantRange TSome = Some.truncate(10);
+ ConstantRange TWrap = Wrap.truncate(10);
+ EXPECT_TRUE(TFull.isFullSet());
+ EXPECT_TRUE(TEmpty.isEmptySet());
+ EXPECT_EQ(TOne, ConstantRange(APInt(One.getLower()).trunc(10),
+ APInt(One.getUpper()).trunc(10)));
+ EXPECT_TRUE(TSome.isFullSet());
+}
+
+TEST_F(ConstantRangeTest, ZExt) {
+ ConstantRange ZFull = Full.zeroExtend(20);
+ ConstantRange ZEmpty = Empty.zeroExtend(20);
+ ConstantRange ZOne = One.zeroExtend(20);
+ ConstantRange ZSome = Some.zeroExtend(20);
+ ConstantRange ZWrap = Wrap.zeroExtend(20);
+ EXPECT_EQ(ZFull, ConstantRange(APInt(20, 0), APInt(20, 0x10000)));
+ EXPECT_TRUE(ZEmpty.isEmptySet());
+ EXPECT_EQ(ZOne, ConstantRange(APInt(One.getLower()).zext(20),
+ APInt(One.getUpper()).zext(20)));
+ EXPECT_EQ(ZSome, ConstantRange(APInt(Some.getLower()).zext(20),
+ APInt(Some.getUpper()).zext(20)));
+ EXPECT_EQ(ZWrap, ConstantRange(APInt(Wrap.getLower()).zext(20),
+ APInt(Wrap.getUpper()).zext(20)));
+}
+
+TEST_F(ConstantRangeTest, SExt) {
+ ConstantRange SFull = Full.signExtend(20);
+ ConstantRange SEmpty = Empty.signExtend(20);
+ ConstantRange SOne = One.signExtend(20);
+ ConstantRange SSome = Some.signExtend(20);
+ ConstantRange SWrap = Wrap.signExtend(20);
+ EXPECT_EQ(SFull, ConstantRange(APInt(20, (uint64_t)INT16_MIN, true),
+ APInt(20, INT16_MAX + 1, true)));
+ EXPECT_TRUE(SEmpty.isEmptySet());
+ EXPECT_EQ(SOne, ConstantRange(APInt(One.getLower()).sext(20),
+ APInt(One.getUpper()).sext(20)));
+ EXPECT_EQ(SSome, ConstantRange(APInt(Some.getLower()).sext(20),
+ APInt(Some.getUpper()).sext(20)));
+ EXPECT_EQ(SWrap, ConstantRange(APInt(Wrap.getLower()).sext(20),
+ APInt(Wrap.getUpper()).sext(20)));
+}
+
+TEST_F(ConstantRangeTest, IntersectWith) {
+ EXPECT_EQ(Empty.intersectWith(Full), Empty);
+ EXPECT_EQ(Empty.intersectWith(Empty), Empty);
+ EXPECT_EQ(Empty.intersectWith(One), Empty);
+ EXPECT_EQ(Empty.intersectWith(Some), Empty);
+ EXPECT_EQ(Empty.intersectWith(Wrap), Empty);
+ EXPECT_EQ(Full.intersectWith(Full), Full);
+ EXPECT_EQ(Some.intersectWith(Some), Some);
+ EXPECT_EQ(Some.intersectWith(One), One);
+ EXPECT_EQ(Full.intersectWith(One), One);
+ EXPECT_EQ(Full.intersectWith(Some), Some);
+ EXPECT_EQ(Some.intersectWith(Wrap), Empty);
+ EXPECT_EQ(One.intersectWith(Wrap), Empty);
+ EXPECT_EQ(One.intersectWith(Wrap), Wrap.intersectWith(One));
+
+ // Klee generated testcase from PR4545.
+ // The intersection of i16 [4, 2) and [6, 5) is disjoint, looking like
+ // 01..4.6789ABCDEF where the dots represent values not in the intersection.
+ ConstantRange LHS(APInt(16, 4), APInt(16, 2));
+ ConstantRange RHS(APInt(16, 6), APInt(16, 5));
+ EXPECT_TRUE(LHS.intersectWith(RHS) == LHS);
+}
+
+TEST_F(ConstantRangeTest, UnionWith) {
+ EXPECT_EQ(Wrap.unionWith(One),
+ ConstantRange(APInt(16, 0xaaa), APInt(16, 0xb)));
+ EXPECT_EQ(One.unionWith(Wrap), Wrap.unionWith(One));
+ EXPECT_EQ(Empty.unionWith(Empty), Empty);
+ EXPECT_EQ(Full.unionWith(Full), Full);
+ EXPECT_EQ(Some.unionWith(Wrap), Full);
+
+ // PR4545
+ EXPECT_EQ(ConstantRange(APInt(16, 14), APInt(16, 1)).unionWith(
+ ConstantRange(APInt(16, 0), APInt(16, 8))),
+ ConstantRange(APInt(16, 14), APInt(16, 8)));
+ EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
+ ConstantRange(APInt(16, 4), APInt(16, 0))),
+ ConstantRange(16));
+ EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
+ ConstantRange(APInt(16, 2), APInt(16, 1))),
+ ConstantRange(16));
+}
+
+TEST_F(ConstantRangeTest, SubtractAPInt) {
+ EXPECT_EQ(Full.subtract(APInt(16, 4)), Full);
+ EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty);
+ EXPECT_EQ(Some.subtract(APInt(16, 4)),
+ ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6)));
+ EXPECT_EQ(Wrap.subtract(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6)));
+ EXPECT_EQ(One.subtract(APInt(16, 4)),
+ ConstantRange(APInt(16, 0x6)));
+}
+
+TEST_F(ConstantRangeTest, Add) {
+ EXPECT_EQ(Full.add(APInt(16, 4)), Full);
+ EXPECT_EQ(Full.add(Full), Full);
+ EXPECT_EQ(Full.add(Empty), Empty);
+ EXPECT_EQ(Full.add(One), Full);
+ EXPECT_EQ(Full.add(Some), Full);
+ EXPECT_EQ(Full.add(Wrap), Full);
+ EXPECT_EQ(Empty.add(Empty), Empty);
+ EXPECT_EQ(Empty.add(One), Empty);
+ EXPECT_EQ(Empty.add(Some), Empty);
+ EXPECT_EQ(Empty.add(Wrap), Empty);
+ EXPECT_EQ(Empty.add(APInt(16, 4)), Empty);
+ EXPECT_EQ(Some.add(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xe), APInt(16, 0xaae)));
+ EXPECT_EQ(Wrap.add(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xaae), APInt(16, 0xe)));
+ EXPECT_EQ(One.add(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xe)));
+}
+
+TEST_F(ConstantRangeTest, Multiply) {
+ EXPECT_EQ(Full.multiply(Full), Full);
+ EXPECT_EQ(Full.multiply(Empty), Empty);
+ EXPECT_EQ(Full.multiply(One), Full);
+ EXPECT_EQ(Full.multiply(Some), Full);
+ EXPECT_EQ(Full.multiply(Wrap), Full);
+ EXPECT_EQ(Empty.multiply(Empty), Empty);
+ EXPECT_EQ(Empty.multiply(One), Empty);
+ EXPECT_EQ(Empty.multiply(Some), Empty);
+ EXPECT_EQ(Empty.multiply(Wrap), Empty);
+ EXPECT_EQ(One.multiply(One), ConstantRange(APInt(16, 0xa*0xa),
+ APInt(16, 0xa*0xa + 1)));
+ EXPECT_EQ(One.multiply(Some), ConstantRange(APInt(16, 0xa*0xa),
+ APInt(16, 0xa*0xaa9 + 1)));
+ EXPECT_EQ(One.multiply(Wrap), Full);
+ EXPECT_EQ(Some.multiply(Some), Full);
+ EXPECT_EQ(Some.multiply(Wrap), Full);
+ EXPECT_EQ(Wrap.multiply(Wrap), Full);
+
+ // http://llvm.org/PR4545
+ EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply(
+ ConstantRange(APInt(4, 6), APInt(4, 2))),
+ ConstantRange(4, /*isFullSet=*/true));
+}
+
+TEST_F(ConstantRangeTest, UMax) {
+ EXPECT_EQ(Full.umax(Full), Full);
+ EXPECT_EQ(Full.umax(Empty), Empty);
+ EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(Full.umax(Wrap), Full);
+ EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(Empty.umax(Empty), Empty);
+ EXPECT_EQ(Empty.umax(Some), Empty);
+ EXPECT_EQ(Empty.umax(Wrap), Empty);
+ EXPECT_EQ(Empty.umax(One), Empty);
+ EXPECT_EQ(Some.umax(Some), Some);
+ EXPECT_EQ(Some.umax(Wrap), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(Some.umax(One), Some);
+ // TODO: ConstantRange is currently over-conservative here.
+ EXPECT_EQ(Wrap.umax(Wrap), Full);
+ EXPECT_EQ(Wrap.umax(One), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(One.umax(One), One);
+}
+
+TEST_F(ConstantRangeTest, SMax) {
+ EXPECT_EQ(Full.smax(Full), Full);
+ EXPECT_EQ(Full.smax(Empty), Empty);
+ EXPECT_EQ(Full.smax(Some), ConstantRange(APInt(16, 0xa),
+ APInt::getSignedMinValue(16)));
+ EXPECT_EQ(Full.smax(Wrap), Full);
+ EXPECT_EQ(Full.smax(One), ConstantRange(APInt(16, 0xa),
+ APInt::getSignedMinValue(16)));
+ EXPECT_EQ(Empty.smax(Empty), Empty);
+ EXPECT_EQ(Empty.smax(Some), Empty);
+ EXPECT_EQ(Empty.smax(Wrap), Empty);
+ EXPECT_EQ(Empty.smax(One), Empty);
+ EXPECT_EQ(Some.smax(Some), Some);
+ EXPECT_EQ(Some.smax(Wrap), ConstantRange(APInt(16, 0xa),
+ APInt(16, (uint64_t)INT16_MIN)));
+ EXPECT_EQ(Some.smax(One), Some);
+ EXPECT_EQ(Wrap.smax(One), ConstantRange(APInt(16, 0xa),
+ APInt(16, (uint64_t)INT16_MIN)));
+ EXPECT_EQ(One.smax(One), One);
+}
+
+TEST_F(ConstantRangeTest, UDiv) {
+ EXPECT_EQ(Full.udiv(Full), Full);
+ EXPECT_EQ(Full.udiv(Empty), Empty);
+ EXPECT_EQ(Full.udiv(One), ConstantRange(APInt(16, 0),
+ APInt(16, 0xffff / 0xa + 1)));
+ EXPECT_EQ(Full.udiv(Some), ConstantRange(APInt(16, 0),
+ APInt(16, 0xffff / 0xa + 1)));
+ EXPECT_EQ(Full.udiv(Wrap), Full);
+ EXPECT_EQ(Empty.udiv(Empty), Empty);
+ EXPECT_EQ(Empty.udiv(One), Empty);
+ EXPECT_EQ(Empty.udiv(Some), Empty);
+ EXPECT_EQ(Empty.udiv(Wrap), Empty);
+ EXPECT_EQ(One.udiv(One), ConstantRange(APInt(16, 1)));
+ EXPECT_EQ(One.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 2)));
+ EXPECT_EQ(One.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
+ EXPECT_EQ(Some.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 0x111)));
+ EXPECT_EQ(Some.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
+ EXPECT_EQ(Wrap.udiv(Wrap), Full);
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp
index 1f19468..3db1f77 100644
--- a/unittests/Support/MathExtrasTest.cpp
+++ b/unittests/Support/MathExtrasTest.cpp
@@ -1,4 +1,4 @@
-//===- llvm/unittest/Support/MathExtrasTest.cpp - math utils tests --------===//
+//===- unittests/Support/MathExtrasTest.cpp - math utils tests ------------===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp
new file mode 100644
index 0000000..44c7e55
--- /dev/null
+++ b/unittests/Support/RegexTest.cpp
@@ -0,0 +1,65 @@
+//===- llvm/unittest/Support/RegexTest.cpp - Regex tests --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cstring>
+
+using namespace llvm;
+namespace {
+
+class RegexTest : public ::testing::Test {
+};
+
+TEST_F(RegexTest, Basics) {
+ Regex r1("^[0-9]+$");
+ EXPECT_TRUE(r1.match("916"));
+ EXPECT_TRUE(r1.match("9"));
+ EXPECT_FALSE(r1.match("9a"));
+
+ SmallVector<StringRef, 1> Matches;
+ Regex r2("[0-9]+");
+ EXPECT_TRUE(r2.match("aa216b", &Matches));
+ EXPECT_EQ(1u, Matches.size());
+ EXPECT_EQ("216", Matches[0].str());
+
+ Regex r3("[0-9]+([a-f])?:([0-9]+)");
+ EXPECT_TRUE(r3.match("9a:513b", &Matches));
+ EXPECT_EQ(3u, Matches.size());
+ EXPECT_EQ("9a:513", Matches[0].str());
+ EXPECT_EQ("a", Matches[1].str());
+ EXPECT_EQ("513", Matches[2].str());
+
+ EXPECT_TRUE(r3.match("9:513b", &Matches));
+ EXPECT_EQ(3u, Matches.size());
+ EXPECT_EQ("9:513", Matches[0].str());
+ EXPECT_EQ("", Matches[1].str());
+ EXPECT_EQ("513", Matches[2].str());
+
+ Regex r4("a[^b]+b");
+ std::string String="axxb";
+ String[2] = '\0';
+ EXPECT_FALSE(r4.match("abb"));
+ EXPECT_TRUE(r4.match(String, &Matches));
+ EXPECT_EQ(1u, Matches.size());
+ EXPECT_EQ(String, Matches[0].str());
+
+
+ std::string NulPattern="X[0-9]+X([a-f])?:([0-9]+)";
+ String="YX99a:513b";
+ NulPattern[7] = '\0';
+ Regex r5(NulPattern);
+ EXPECT_FALSE(r5.match(String));
+ EXPECT_FALSE(r5.match("X9"));
+ String[3]='\0';
+ EXPECT_TRUE(r5.match(String));
+}
+
+}
diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp
index 425ee6b..a5c5e67 100644
--- a/unittests/Support/TypeBuilderTest.cpp
+++ b/unittests/Support/TypeBuilderTest.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/TypeBuilder.h"
+#include "llvm/LLVMContext.h"
#include "gtest/gtest.h"
@@ -16,134 +17,146 @@ using namespace llvm;
namespace {
TEST(TypeBuilderTest, Void) {
- EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, true>::get()));
- EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, false>::get()));
+ EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext())));
// Special case for C compatibility:
- EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty),
- (TypeBuilder<void*, false>::get()));
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<void*, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, HostIntegers) {
- EXPECT_EQ(Type::Int8Ty, (TypeBuilder<int8_t, false>::get()));
- EXPECT_EQ(Type::Int8Ty, (TypeBuilder<uint8_t, false>::get()));
- EXPECT_EQ(Type::Int16Ty, (TypeBuilder<int16_t, false>::get()));
- EXPECT_EQ(Type::Int16Ty, (TypeBuilder<uint16_t, false>::get()));
- EXPECT_EQ(Type::Int32Ty, (TypeBuilder<int32_t, false>::get()));
- EXPECT_EQ(Type::Int32Ty, (TypeBuilder<uint32_t, false>::get()));
- EXPECT_EQ(Type::Int64Ty, (TypeBuilder<int64_t, false>::get()));
- EXPECT_EQ(Type::Int64Ty, (TypeBuilder<uint64_t, false>::get()));
-
- EXPECT_EQ(IntegerType::get(sizeof(size_t) * CHAR_BIT),
- (TypeBuilder<size_t, false>::get()));
- EXPECT_EQ(IntegerType::get(sizeof(ptrdiff_t) * CHAR_BIT),
- (TypeBuilder<ptrdiff_t, false>::get()));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext())));
+
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT),
+ (TypeBuilder<size_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT),
+ (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, CrossCompilableIntegers) {
- EXPECT_EQ(IntegerType::get(1), (TypeBuilder<types::i<1>, true>::get()));
- EXPECT_EQ(IntegerType::get(1), (TypeBuilder<types::i<1>, false>::get()));
- EXPECT_EQ(IntegerType::get(72), (TypeBuilder<types::i<72>, true>::get()));
- EXPECT_EQ(IntegerType::get(72), (TypeBuilder<types::i<72>, false>::get()));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, Float) {
- EXPECT_EQ(Type::FloatTy, (TypeBuilder<float, false>::get()));
- EXPECT_EQ(Type::DoubleTy, (TypeBuilder<double, false>::get()));
+ EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext())));
// long double isn't supported yet.
- EXPECT_EQ(Type::FloatTy, (TypeBuilder<types::ieee_float, true>::get()));
- EXPECT_EQ(Type::FloatTy, (TypeBuilder<types::ieee_float, false>::get()));
- EXPECT_EQ(Type::DoubleTy, (TypeBuilder<types::ieee_double, true>::get()));
- EXPECT_EQ(Type::DoubleTy, (TypeBuilder<types::ieee_double, false>::get()));
- EXPECT_EQ(Type::X86_FP80Ty, (TypeBuilder<types::x86_fp80, true>::get()));
- EXPECT_EQ(Type::X86_FP80Ty, (TypeBuilder<types::x86_fp80, false>::get()));
- EXPECT_EQ(Type::FP128Ty, (TypeBuilder<types::fp128, true>::get()));
- EXPECT_EQ(Type::FP128Ty, (TypeBuilder<types::fp128, false>::get()));
- EXPECT_EQ(Type::PPC_FP128Ty, (TypeBuilder<types::ppc_fp128, true>::get()));
- EXPECT_EQ(Type::PPC_FP128Ty, (TypeBuilder<types::ppc_fp128, false>::get()));
+ EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, Derived) {
- EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)),
- (TypeBuilder<int8_t**, false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7),
- (TypeBuilder<int8_t[7], false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0),
- (TypeBuilder<int8_t[], false>::get()));
-
- EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)),
- (TypeBuilder<types::i<8>**, false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7),
- (TypeBuilder<types::i<8>[7], false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0),
- (TypeBuilder<types::i<8>[], false>::get()));
-
- EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)),
- (TypeBuilder<types::i<8>**, true>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7),
- (TypeBuilder<types::i<8>[7], true>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0),
- (TypeBuilder<types::i<8>[], true>::get()));
-
-
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const int8_t, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<volatile int8_t, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const volatile int8_t, false>::get()));
-
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const types::i<8>, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<volatile types::i<8>, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const volatile types::i<8>, false>::get()));
-
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const types::i<8>, true>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<volatile types::i<8>, true>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const volatile types::i<8>, true>::get()));
-
- EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty),
- (TypeBuilder<const volatile int8_t*const volatile, false>::get()));
+ EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+ (TypeBuilder<int8_t**, false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+ (TypeBuilder<int8_t[7], false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+ (TypeBuilder<int8_t[], false>::get(getGlobalContext())));
+
+ EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+ (TypeBuilder<types::i<8>**, false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+ (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+ (TypeBuilder<types::i<8>[], false>::get(getGlobalContext())));
+
+ EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+ (TypeBuilder<types::i<8>**, true>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+ (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+ (TypeBuilder<types::i<8>[], true>::get(getGlobalContext())));
+
+
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const int8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<volatile int8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext())));
+
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const types::i<8>, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext())));
+
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const types::i<8>, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext())));
+
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, Functions) {
std::vector<const Type*> params;
- EXPECT_EQ(FunctionType::get(Type::VoidTy, params, false),
- (TypeBuilder<void(), true>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(...), false>::get()));
- params.push_back(TypeBuilder<int32_t*, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(const int32_t*), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(const int32_t*, ...), false>::get()));
- params.push_back(TypeBuilder<char*, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(int32_t*, void*), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get()));
- params.push_back(TypeBuilder<char, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(int32_t*, void*, char), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get()));
- params.push_back(TypeBuilder<char, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
+ EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false),
+ (TypeBuilder<void(), true>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char*, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
(TypeBuilder<int8_t(int32_t*, char*, char, char, ...),
- false>::get()));
- params.push_back(TypeBuilder<char, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
+ false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
(TypeBuilder<int8_t(int32_t*, void*, char, char, char),
- false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
+ false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
(TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...),
- false>::get()));
+ false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, Context) {
+ // We used to cache TypeBuilder results in static local variables. This
+ // produced the same type for different contexts, which of course broke
+ // things.
+ LLVMContext context1;
+ EXPECT_EQ(&context1,
+ &(TypeBuilder<types::i<1>, true>::get(context1))->getContext());
+ LLVMContext context2;
+ EXPECT_EQ(&context2,
+ &(TypeBuilder<types::i<1>, true>::get(context2))->getContext());
}
class MyType {
@@ -163,14 +176,14 @@ class MyPortableType {
namespace llvm {
template<bool cross> class TypeBuilder<MyType, cross> {
public:
- static const StructType *get() {
+ static const StructType *get(LLVMContext &Context) {
// Using the static result variable ensures that the type is
// only looked up once.
- static const StructType *const result = StructType::get(
- TypeBuilder<int, cross>::get(),
- TypeBuilder<int*, cross>::get(),
- TypeBuilder<void*[], cross>::get(),
- NULL);
+ std::vector<const Type*> st;
+ st.push_back(TypeBuilder<int, cross>::get(Context));
+ st.push_back(TypeBuilder<int*, cross>::get(Context));
+ st.push_back(TypeBuilder<void*[], cross>::get(Context));
+ static const StructType *const result = StructType::get(Context, st);
return result;
}
@@ -186,14 +199,14 @@ public:
template<bool cross> class TypeBuilder<MyPortableType, cross> {
public:
- static const StructType *get() {
+ static const StructType *get(LLVMContext &Context) {
// Using the static result variable ensures that the type is
// only looked up once.
- static const StructType *const result = StructType::get(
- TypeBuilder<types::i<32>, cross>::get(),
- TypeBuilder<types::i<32>*, cross>::get(),
- TypeBuilder<types::i<8>*[], cross>::get(),
- NULL);
+ std::vector<const Type*> st;
+ st.push_back(TypeBuilder<types::i<32>, cross>::get(Context));
+ st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context));
+ st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context));
+ static const StructType *const result = StructType::get(Context, st);
return result;
}
@@ -210,24 +223,24 @@ public:
namespace {
TEST(TypeBuilderTest, Extensions) {
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<int, false>::get(),
- TypeBuilder<int*, false>::get(),
- TypeBuilder<void*[], false>::get(),
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(getGlobalContext(),
+ TypeBuilder<int, false>::get(getGlobalContext()),
+ TypeBuilder<int*, false>::get(getGlobalContext()),
+ TypeBuilder<void*[], false>::get(getGlobalContext()),
NULL)),
- (TypeBuilder<MyType*, false>::get()));
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(),
- TypeBuilder<types::i<32>*, false>::get(),
- TypeBuilder<types::i<8>*[], false>::get(),
+ (TypeBuilder<MyType*, false>::get(getGlobalContext())));
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(getGlobalContext(),
+ TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
NULL)),
- (TypeBuilder<MyPortableType*, false>::get()));
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(),
- TypeBuilder<types::i<32>*, false>::get(),
- TypeBuilder<types::i<8>*[], false>::get(),
+ (TypeBuilder<MyPortableType*, false>::get(getGlobalContext())));
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(getGlobalContext(),
+ TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
NULL)),
- (TypeBuilder<MyPortableType*, true>::get()));
+ (TypeBuilder<MyPortableType*, true>::get(getGlobalContext())));
}
} // anonymous namespace
diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp
index 336e7d9..c89a7af 100644
--- a/unittests/Support/ValueHandleTest.cpp
+++ b/unittests/Support/ValueHandleTest.cpp
@@ -11,6 +11,7 @@
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/ADT/OwningPtr.h"
#include "gtest/gtest.h"
@@ -25,8 +26,9 @@ protected:
Constant *ConstantV;
std::auto_ptr<BitCastInst> BitcastV;
- ValueHandle() : ConstantV(ConstantInt::get(Type::Int32Ty, 0)),
- BitcastV(new BitCastInst(ConstantV, Type::Int32Ty)) {
+ ValueHandle() :
+ ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
+ BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
}
};
@@ -44,8 +46,8 @@ TEST_F(ValueHandle, WeakVH_BasicOperation) {
// Make sure I can call a method on the underlying Value. It
// doesn't matter which method.
- EXPECT_EQ(Type::Int32Ty, WVH->getType());
- EXPECT_EQ(Type::Int32Ty, (*WVH).getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
}
TEST_F(ValueHandle, WeakVH_Comparisons) {
@@ -119,6 +121,13 @@ TEST_F(ValueHandle, AssertingVH_BasicOperation) {
EXPECT_FALSE((*AVH).mayWriteToMemory());
}
+TEST_F(ValueHandle, AssertingVH_Const) {
+ const CastInst *ConstBitcast = BitcastV.get();
+ AssertingVH<const CastInst> AVH(ConstBitcast);
+ const CastInst *implicit_to_exact_type = AVH;
+ implicit_to_exact_type = implicit_to_exact_type; // Avoid warning.
+}
+
TEST_F(ValueHandle, AssertingVH_Comparisons) {
AssertingVH<Value> BitcastAVH(BitcastV.get());
AssertingVH<Value> ConstantAVH(ConstantV);
@@ -192,8 +201,8 @@ TEST_F(ValueHandle, CallbackVH_BasicOperation) {
// Make sure I can call a method on the underlying Value. It
// doesn't matter which method.
- EXPECT_EQ(Type::Int32Ty, CVH->getType());
- EXPECT_EQ(Type::Int32Ty, (*CVH).getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
}
TEST_F(ValueHandle, CallbackVH_Comparisons) {
@@ -284,14 +293,17 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
public:
int DeletedCalls;
Value *AURWArgument;
+ LLVMContext *Context;
- RecoveringVH() : DeletedCalls(0), AURWArgument(NULL) {}
+ RecoveringVH() : DeletedCalls(0), AURWArgument(NULL),
+ Context(&getGlobalContext()) {}
RecoveringVH(Value *V)
- : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
+ : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL),
+ Context(&getGlobalContext()) {}
private:
virtual void deleted() {
- getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty));
+ getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
setValPtr(NULL);
}
virtual void allUsesReplacedWith(Value *new_value) {
@@ -307,11 +319,93 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
RecoveringVH RVH;
RVH = BitcastV.get();
std::auto_ptr<BinaryOperator> BitcastUser(
- BinaryOperator::CreateAdd(RVH, Constant::getNullValue(Type::Int32Ty)));
+ BinaryOperator::CreateAdd(RVH,
+ Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
BitcastV.reset(); // Would crash without the ValueHandler.
- EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), RVH.AURWArgument);
- EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), BitcastUser->getOperand(0));
+ EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
+ EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
+ BitcastUser->getOperand(0));
+}
+
+TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
+ // When a CallbackVH modifies other ValueHandles in its callbacks,
+ // that shouldn't interfere with non-modified ValueHandles receiving
+ // their appropriate callbacks.
+ //
+ // We create the active CallbackVH in the middle of a palindromic
+ // arrangement of other VHs so that the bad behavior would be
+ // triggered in whichever order callbacks run.
+
+ class DestroyingVH : public CallbackVH {
+ public:
+ OwningPtr<WeakVH> ToClear[2];
+ DestroyingVH(Value *V) {
+ ToClear[0].reset(new WeakVH(V));
+ setValPtr(V);
+ ToClear[1].reset(new WeakVH(V));
+ }
+ virtual void deleted() {
+ ToClear[0].reset();
+ ToClear[1].reset();
+ CallbackVH::deleted();
+ }
+ virtual void allUsesReplacedWith(Value *) {
+ ToClear[0].reset();
+ ToClear[1].reset();
+ }
+ };
+
+ {
+ WeakVH ShouldBeVisited1(BitcastV.get());
+ DestroyingVH C(BitcastV.get());
+ WeakVH ShouldBeVisited2(BitcastV.get());
+
+ BitcastV->replaceAllUsesWith(ConstantV);
+ EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
+ EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
+ }
+
+ {
+ WeakVH ShouldBeVisited1(BitcastV.get());
+ DestroyingVH C(BitcastV.get());
+ WeakVH ShouldBeVisited2(BitcastV.get());
+
+ BitcastV.reset();
+ EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
+ EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
+ }
+}
+
+TEST_F(ValueHandle, AssertingVHCheckedLast) {
+ // If a CallbackVH exists to clear out a group of AssertingVHs on
+ // Value deletion, the CallbackVH should get a chance to do so
+ // before the AssertingVHs assert.
+
+ class ClearingVH : public CallbackVH {
+ public:
+ AssertingVH<Value> *ToClear[2];
+ ClearingVH(Value *V,
+ AssertingVH<Value> &A0, AssertingVH<Value> &A1)
+ : CallbackVH(V) {
+ ToClear[0] = &A0;
+ ToClear[1] = &A1;
+ }
+
+ virtual void deleted() {
+ *ToClear[0] = 0;
+ *ToClear[1] = 0;
+ CallbackVH::deleted();
+ }
+ };
+
+ AssertingVH<Value> A1, A2;
+ A1 = BitcastV.get();
+ ClearingVH C(BitcastV.get(), A1, A2);
+ A2 = BitcastV.get();
+ // C.deleted() should run first, clearing the two AssertingVHs,
+ // which should prevent them from asserting.
+ BitcastV.reset();
}
}
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index feb0152..bd2e95c 100644
--- a/unittests/Support/raw_ostream_test.cpp
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -20,6 +22,23 @@ template<typename T> std::string printToString(const T &Value) {
return res;
}
+/// printToString - Print the given value to a stream which only has \arg
+/// BytesLeftInBuffer bytes left in the buffer. This is useful for testing edge
+/// cases in the buffer handling logic.
+template<typename T> std::string printToString(const T &Value,
+ unsigned BytesLeftInBuffer) {
+ // FIXME: This is relying on internal knowledge of how raw_ostream works to
+ // get the buffer position right.
+ SmallString<256> SVec;
+ assert(BytesLeftInBuffer < 256 && "Invalid buffer count!");
+ llvm::raw_svector_ostream OS(SVec);
+ unsigned StartIndex = 256 - BytesLeftInBuffer;
+ for (unsigned i = 0; i != StartIndex; ++i)
+ OS << '?';
+ OS << Value;
+ return OS.str().substr(StartIndex);
+}
+
template<typename T> std::string printToStringUnbuffered(const T &Value) {
std::string res;
llvm::raw_string_ostream OS(res);
@@ -53,6 +72,10 @@ TEST(raw_ostreamTest, Types_Buffered) {
EXPECT_EQ("0x0", printToString((void*) 0));
EXPECT_EQ("0xbeef", printToString((void*) 0xbeef));
EXPECT_EQ("0xdeadbeef", printToString((void*) 0xdeadbeef));
+
+ // Min and max.
+ EXPECT_EQ("18446744073709551615", printToString(UINT64_MAX));
+ EXPECT_EQ("-9223372036854775808", printToString(INT64_MIN));
}
TEST(raw_ostreamTest, Types_Unbuffered) {
@@ -80,6 +103,28 @@ TEST(raw_ostreamTest, Types_Unbuffered) {
EXPECT_EQ("0x0", printToStringUnbuffered((void*) 0));
EXPECT_EQ("0xbeef", printToStringUnbuffered((void*) 0xbeef));
EXPECT_EQ("0xdeadbeef", printToStringUnbuffered((void*) 0xdeadbeef));
+
+ // Min and max.
+ EXPECT_EQ("18446744073709551615", printToStringUnbuffered(UINT64_MAX));
+ EXPECT_EQ("-9223372036854775808", printToStringUnbuffered(INT64_MIN));
+}
+
+TEST(raw_ostreamTest, BufferEdge) {
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 1));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 2));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 3));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 4));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 10));
+}
+
+TEST(raw_ostreamTest, TinyBuffer) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ OS.SetBufferSize(1);
+ OS << "hello";
+ OS << 1;
+ OS << 'w' << 'o' << 'r' << 'l' << 'd';
+ EXPECT_EQ("hello1world", OS.str());
}
}
OpenPOWER on IntegriCloud