mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239646 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
69fb65b52e
commit
21a987d1ac
@ -1802,7 +1802,9 @@ LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
|
|||||||
LLVMBool Result = Linker::LinkModules(
|
LLVMBool Result = Linker::LinkModules(
|
||||||
D, unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); });
|
D, unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); });
|
||||||
|
|
||||||
if (OutMessages && Result)
|
if (OutMessages && Result) {
|
||||||
|
Stream.flush();
|
||||||
*OutMessages = strdup(Message.c_str());
|
*OutMessages = strdup(Message.c_str());
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/Linker/Linker.h"
|
#include "llvm/Linker/Linker.h"
|
||||||
#include "llvm/Support/SourceMgr.h"
|
#include "llvm/Support/SourceMgr.h"
|
||||||
|
#include "llvm-c/Linker.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -125,6 +126,22 @@ TEST_F(LinkModuleTest, BlockAddress) {
|
|||||||
delete LinkedModule;
|
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) {
|
static Module *getInternal(LLVMContext &Ctx) {
|
||||||
Module *InternalM = new Module("InternalModule", Ctx);
|
Module *InternalM = new Module("InternalModule", Ctx);
|
||||||
FunctionType *FTy = FunctionType::get(
|
FunctionType *FTy = FunctionType::get(
|
||||||
@ -178,4 +195,27 @@ TEST_F(LinkModuleTest, TypeMerge) {
|
|||||||
M1->getNamedGlobal("t2")->getType());
|
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
|
} // end anonymous namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user