diff options
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITTest.cpp | 50 | ||||
-rw-r--r-- | unittests/VMCore/MetadataTest.cpp | 29 |
2 files changed, 68 insertions, 11 deletions
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index 84ee0e3..b85f724 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -65,6 +65,8 @@ public: stubsAllocated = 0; } + void setSizeRequired(bool Required) { SizeRequired = Required; } + virtual void setMemoryWritable() { Base->setMemoryWritable(); } virtual void setMemoryExecutable() { Base->setMemoryExecutable(); } virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); } @@ -628,6 +630,54 @@ TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) { << " not 7 from the IR version."; } +TEST_F(JITTest, NeedsExactSizeWithManyGlobals) { + // PR5291: When the JMM needed the exact size of function bodies before + // starting to emit them, the JITEmitter would modify a set while iterating + // over it. + TheJIT->DisableLazyCompilation(true); + RJMM->setSizeRequired(true); + + LoadAssembly("@A = global i32 42 " + "@B = global i32* @A " + "@C = global i32** @B " + "@D = global i32*** @C " + "@E = global i32**** @D " + "@F = global i32***** @E " + "@G = global i32****** @F " + "@H = global i32******* @G " + "@I = global i32******** @H " + "define i32********* @test() { " + " ret i32********* @I " + "}"); + Function *testIR = M->getFunction("test"); + int32_t********* (*test)() = reinterpret_cast<int32_t*********(*)()>( + (intptr_t)TheJIT->getPointerToFunction(testIR)); + EXPECT_EQ(42, *********test()); +} + +TEST_F(JITTest, EscapedLazyStubStillCallable) { + TheJIT->DisableLazyCompilation(false); + LoadAssembly("define internal i32 @stubbed() { " + " ret i32 42 " + "} " + " " + "define i32()* @get_stub() { " + " ret i32()* @stubbed " + "} "); + typedef int32_t(*StubTy)(); + + // Call get_stub() to get the address of @stubbed without actually JITting it. + Function *get_stubIR = M->getFunction("get_stub"); + StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>( + (intptr_t)TheJIT->getPointerToFunction(get_stubIR)); + StubTy stubbed = get_stub(); + // Now get_stubIR is the only reference to stubbed's stub. + get_stubIR->eraseFromParent(); + // Now there are no references inside the JIT, but we've got a pointer outside + // it. The stub should be callable and return the right value. + EXPECT_EQ(42, stubbed()); +} + // Converts the LLVM assembly to bitcode and returns it in a std::string. An // empty string indicates an error. std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) { diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp index e374789..13bf27e 100644 --- a/unittests/VMCore/MetadataTest.cpp +++ b/unittests/VMCore/MetadataTest.cpp @@ -20,11 +20,15 @@ using namespace llvm; namespace { -LLVMContext &Context = getGlobalContext(); +class MetadataTest : public testing::Test { +protected: + LLVMContext Context; +}; +typedef MetadataTest MDStringTest; // Test that construction of MDString with different value produces different // MDString objects, even with the same string pointer and nulls in the string. -TEST(MDStringTest, CreateDifferent) { +TEST_F(MDStringTest, CreateDifferent) { char x[3] = { 'f', 0, 'A' }; MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); x[2] = 'B'; @@ -34,7 +38,7 @@ TEST(MDStringTest, CreateDifferent) { // Test that creation of MDStrings with the same string contents produces the // same MDString object, even with different pointers. -TEST(MDStringTest, CreateSame) { +TEST_F(MDStringTest, CreateSame) { char x[4] = { 'a', 'b', 'c', 'X' }; char y[4] = { 'a', 'b', 'c', 'Y' }; @@ -44,7 +48,7 @@ TEST(MDStringTest, CreateSame) { } // Test that MDString prints out the string we fed it. -TEST(MDStringTest, PrintingSimple) { +TEST_F(MDStringTest, PrintingSimple) { char *str = new char[13]; strncpy(str, "testing 1 2 3", 13); MDString *s = MDString::get(Context, StringRef(str, 13)); @@ -58,7 +62,7 @@ TEST(MDStringTest, PrintingSimple) { } // Test printing of MDString with non-printable characters. -TEST(MDStringTest, PrintingComplex) { +TEST_F(MDStringTest, PrintingComplex) { char str[5] = {0, '\n', '"', '\\', -1}; MDString *s = MDString::get(Context, StringRef(str+0, 5)); std::string Str; @@ -67,8 +71,10 @@ TEST(MDStringTest, PrintingComplex) { EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str()); } +typedef MetadataTest MDNodeTest; + // Test the two constructors, and containing other Constants. -TEST(MDNodeTest, Simple) { +TEST_F(MDNodeTest, Simple) { char x[3] = { 'a', 'b', 'c' }; char y[3] = { '1', '2', '3' }; @@ -101,7 +107,7 @@ TEST(MDNodeTest, Simple) { EXPECT_EQ(n1, n2->getOperand(0)); } -TEST(MDNodeTest, Delete) { +TEST_F(MDNodeTest, Delete) { Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1); Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext())); @@ -115,8 +121,9 @@ TEST(MDNodeTest, Delete) { } TEST(NamedMDNodeTest, Search) { - Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1); - Constant *C2 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 2); + LLVMContext Context; + Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1); + Constant *C2 = ConstantInt::get(Type::getInt32Ty(Context), 2); Value *const V = C; Value *const V2 = C2; @@ -125,9 +132,9 @@ TEST(NamedMDNodeTest, Search) { MDNode *Nodes[2] = { n, n2 }; - Module *M = new Module("MyModule", getGlobalContext()); + Module *M = new Module("MyModule", Context); const char *Name = "llvm.NMD1"; - NamedMDNode *NMD = NamedMDNode::Create(getGlobalContext(), Name, &Nodes[0], 2, M); + NamedMDNode *NMD = NamedMDNode::Create(Context, Name, &Nodes[0], 2, M); std::string Str; raw_string_ostream oss(Str); NMD->print(oss); |