diff options
| author | Eli Bendersky <eliben@google.com> | 2015-06-12 23:26:42 +0000 |
|---|---|---|
| committer | Eli Bendersky <eliben@google.com> | 2015-06-12 23:26:42 +0000 |
| commit | ff715e2d5ec91e971daa70fdcfc153903030cd15 (patch) | |
| tree | 0f1057d8c7051b460e51462df30be4b035963b14 /llvm/unittests/Linker/LinkModulesTest.cpp | |
| parent | 37cc9fadd5932a60bd708a1b260dea5a999ee668 (diff) | |
| download | llvm-ff715e2d5ec91e971daa70fdcfc153903030cd15.zip llvm-ff715e2d5ec91e971daa70fdcfc153903030cd15.tar.gz llvm-ff715e2d5ec91e971daa70fdcfc153903030cd15.tar.bz2 | |
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
llvm-svn: 239646
Diffstat (limited to 'llvm/unittests/Linker/LinkModulesTest.cpp')
| -rw-r--r-- | llvm/unittests/Linker/LinkModulesTest.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/llvm/unittests/Linker/LinkModulesTest.cpp b/llvm/unittests/Linker/LinkModulesTest.cpp index b4689cb..58a3e72 100644 --- a/llvm/unittests/Linker/LinkModulesTest.cpp +++ b/llvm/unittests/Linker/LinkModulesTest.cpp @@ -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 |
