diff options
author | Jeffrey Yasskin <jyasskin@google.com> | 2009-12-22 23:18:18 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@google.com> | 2009-12-22 23:18:18 +0000 |
commit | 92fdf4537bd298673552d47adac2ff7bceab9dc9 (patch) | |
tree | cc1b23da37c2a4bbc99761558490360044203fe1 /unittests | |
parent | 167bea71a4bd19329a218f5e1bd8facfd90a0cf9 (diff) | |
download | external_llvm-92fdf4537bd298673552d47adac2ff7bceab9dc9.zip external_llvm-92fdf4537bd298673552d47adac2ff7bceab9dc9.tar.gz external_llvm-92fdf4537bd298673552d47adac2ff7bceab9dc9.tar.bz2 |
Fix a crash in JIT::recompileAndRelinkFunction(). It doesn't pass the MCI
argument to runJITOnFunction(), which caused a null pointer dereference at
every call.
Patch by Gianluca Guida!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91939 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITTest.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index da4dfc4..c6c26c7 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -534,6 +534,37 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) { #endif } +TEST_F(JITTest, FunctionIsRecompiledAndRelinked) { + Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context), + GlobalValue::ExternalLinkage, "test", M); + BasicBlock *Entry = BasicBlock::Create(Context, "entry", F); + IRBuilder<> Builder(Entry); + Value *Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 1); + Builder.CreateRet(Val); + + TheJIT->DisableLazyCompilation(true); + // Compile the function once, and make sure it works. + int (*OrigFPtr)() = reinterpret_cast<int(*)()>( + (intptr_t)TheJIT->recompileAndRelinkFunction(F)); + EXPECT_EQ(1, OrigFPtr()); + + // Now change the function to return a different value. + Entry->eraseFromParent(); + BasicBlock *NewEntry = BasicBlock::Create(Context, "new_entry", F); + Builder.SetInsertPoint(NewEntry); + Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 2); + Builder.CreateRet(Val); + // Recompile it, which should produce a new function pointer _and_ update the + // old one. + int (*NewFPtr)() = reinterpret_cast<int(*)()>( + (intptr_t)TheJIT->recompileAndRelinkFunction(F)); + + EXPECT_EQ(2, NewFPtr()) + << "The new pointer should call the new version of the function"; + EXPECT_EQ(2, OrigFPtr()) + << "The old pointer's target should now jump to the new version"; +} + } // anonymous namespace // This variable is intentionally defined differently in the statically-compiled // program from the IR input to the JIT to assert that the JIT doesn't use its |