[MCJIT] Make repeat calls to MCJIT::getPointerToFunction for declarations safe.
authorLang Hames <lhames@gmail.com>
Wed, 22 Oct 2014 23:18:42 +0000 (23:18 +0000)
committerLang Hames <lhames@gmail.com>
Wed, 22 Oct 2014 23:18:42 +0000 (23:18 +0000)
MCJIT::getPointerForFunction adds the resulting address to the global mapping.
This should be done via updateGlobalMapping rather than addGlobalMapping, since
the latter asserts if a mapping already exists.

MCJIT::getPointerToFunction is actually deprecated - hopefully we can remove it
(or more likely re-task it) entirely soon. In the mean time it should at least
work as advertised.

<rdar://problem/18727946>

llvm-svn: 220444

llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h

index 9469d10..8f1662f 100644 (file)
@@ -357,7 +357,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
   if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
     bool AbortOnFailure = !F->hasExternalWeakLinkage();
     void *Addr = getPointerToNamedFunction(Name, AbortOnFailure);
-    addGlobalMapping(F, Addr);
+    updateGlobalMapping(F, Addr);
     return Addr;
   }
 
index 15e0efd..64d8c2f 100644 (file)
@@ -187,4 +187,16 @@ TEST_F(MCJITTest, multiple_functions) {
 
 #endif /*!defined(__arm__)*/
 
+TEST_F(MCJITTest, multiple_decl_lookups) {
+  SKIP_UNSUPPORTED_PLATFORM;
+
+  Function *Foo = insertExternalReferenceToFunction<void(void)>(M.get(), "_exit");
+  createJIT(std::move(M));
+  void *A = TheJIT->getPointerToFunction(Foo);
+  void *B = TheJIT->getPointerToFunction(Foo);
+
+  EXPECT_TRUE(A != 0) << "Failed lookup - test not correctly configured.";
+  EXPECT_EQ(A, B) << "Repeat calls to getPointerToFunction fail.";
+}
+
 }
index bc44418..eea88bb 100644 (file)
@@ -107,6 +107,15 @@ protected:
     return Result;
   }
 
+  // Inserts a declaration to a function defined elsewhere
+  template <typename FuncType>
+  Function *insertExternalReferenceToFunction(Module *M, StringRef Name) {
+    Function *Result = Function::Create(
+                         TypeBuilder<FuncType, false>::get(Context),
+                         GlobalValue::ExternalLinkage, Name, M);
+    return Result;
+  }
+
   // Inserts an declaration to a function defined elsewhere
   Function *insertExternalReferenceToFunction(Module *M, StringRef Name,
                                               FunctionType *FuncTy) {