[llvm] r239646 - Fix returning error message in LLVMLinkModules

Eli Bendersky eliben at google.com
Fri Jun 12 16:26:42 PDT 2015


Author: eliben
Date: Fri Jun 12 18:26:42 2015
New Revision: 239646

URL: http://llvm.org/viewvc/llvm-project?rev=239646&view=rev
Log:
Fix returning error message in LLVMLinkModules

On error, the temporary output stream wouldn't be flushed and therefore the
caller would see an empty error message.

Patch by Antoine Pitrou

Differential Revision: http://reviews.llvm.org/D10241 

Modified:
    llvm/trunk/lib/Linker/LinkModules.cpp
    llvm/trunk/unittests/Linker/LinkModulesTest.cpp

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=239646&r1=239645&r2=239646&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Fri Jun 12 18:26:42 2015
@@ -1802,7 +1802,9 @@ LLVMBool LLVMLinkModules(LLVMModuleRef D
   LLVMBool Result = Linker::LinkModules(
       D, unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); });
 
-  if (OutMessages && Result)
+  if (OutMessages && Result) {
+    Stream.flush();
     *OutMessages = strdup(Message.c_str());
+  }
   return Result;
 }

Modified: llvm/trunk/unittests/Linker/LinkModulesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Linker/LinkModulesTest.cpp?rev=239646&r1=239645&r2=239646&view=diff
==============================================================================
--- llvm/trunk/unittests/Linker/LinkModulesTest.cpp (original)
+++ llvm/trunk/unittests/Linker/LinkModulesTest.cpp Fri Jun 12 18:26:42 2015
@@ -15,6 +15,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Linker/Linker.h"
 #include "llvm/Support/SourceMgr.h"
+#include "llvm-c/Linker.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -125,6 +126,22 @@ TEST_F(LinkModuleTest, BlockAddress) {
   delete LinkedModule;
 }
 
+static Module *getExternal(LLVMContext &Ctx, StringRef FuncName) {
+  // Create a module with an empty externally-linked function
+  Module *M = new Module("ExternalModule", Ctx);
+  FunctionType *FTy = FunctionType::get(
+      Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
+
+  Function *F =
+      Function::Create(FTy, Function::ExternalLinkage, FuncName, M);
+  F->setCallingConv(CallingConv::C);
+
+  BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
+  IRBuilder<> Builder(BB);
+  Builder.CreateRetVoid();
+  return M;
+}
+
 static Module *getInternal(LLVMContext &Ctx) {
   Module *InternalM = new Module("InternalModule", Ctx);
   FunctionType *FTy = FunctionType::get(
@@ -178,4 +195,27 @@ TEST_F(LinkModuleTest, TypeMerge) {
             M1->getNamedGlobal("t2")->getType());
 }
 
+TEST_F(LinkModuleTest, CAPISuccess) {
+  std::unique_ptr<Module> DestM(getExternal(Ctx, "foo"));
+  std::unique_ptr<Module> SourceM(getExternal(Ctx, "bar"));
+  char *errout = nullptr;
+  LLVMBool result = LLVMLinkModules(wrap(DestM.get()), wrap(SourceM.get()),
+                                    LLVMLinkerDestroySource, &errout);
+  EXPECT_EQ(0, result);
+  EXPECT_EQ(nullptr, errout);
+  // "bar" is present in destination module
+  EXPECT_NE(nullptr, DestM->getFunction("bar"));
+}
+
+TEST_F(LinkModuleTest, CAPIFailure) {
+  // Symbol clash between two modules
+  std::unique_ptr<Module> DestM(getExternal(Ctx, "foo"));
+  std::unique_ptr<Module> SourceM(getExternal(Ctx, "foo"));
+  char *errout = nullptr;
+  LLVMBool result = LLVMLinkModules(wrap(DestM.get()), wrap(SourceM.get()),
+                                    LLVMLinkerDestroySource, &errout);
+  EXPECT_EQ(1, result);
+  EXPECT_STREQ("Linking globals named 'foo': symbol multiply defined!", errout);
+}
+
 } // end anonymous namespace





More information about the llvm-commits mailing list