diff options
Diffstat (limited to 'unittests/ExecutionEngine/JIT/JITTest.cpp')
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITTest.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index 84ee0e3075..168bb3cb98 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,31 @@ 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()); +} + // 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) { |