LinkModulesTest.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. //===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/AsmParser/Parser.h"
  10. #include "llvm/IR/BasicBlock.h"
  11. #include "llvm/IR/DataLayout.h"
  12. #include "llvm/IR/Function.h"
  13. #include "llvm/IR/IRBuilder.h"
  14. #include "llvm/IR/Module.h"
  15. #include "llvm/Linker/Linker.h"
  16. #include "llvm/Support/SourceMgr.h"
  17. #include "llvm-c/Linker.h"
  18. #include "gtest/gtest.h"
  19. using namespace llvm;
  20. namespace {
  21. class LinkModuleTest : public testing::Test {
  22. protected:
  23. void SetUp() override {
  24. M.reset(new Module("MyModule", Ctx));
  25. FunctionType *FTy = FunctionType::get(
  26. Type::getInt8PtrTy(Ctx), Type::getInt32Ty(Ctx), false /*=isVarArg*/);
  27. F = Function::Create(FTy, Function::ExternalLinkage, "ba_func", M.get());
  28. F->setCallingConv(CallingConv::C);
  29. EntryBB = BasicBlock::Create(Ctx, "entry", F);
  30. SwitchCase1BB = BasicBlock::Create(Ctx, "switch.case.1", F);
  31. SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F);
  32. ExitBB = BasicBlock::Create(Ctx, "exit", F);
  33. AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
  34. GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/,
  35. GlobalValue::InternalLinkage, nullptr,"switch.bas");
  36. // Global Initializer
  37. std::vector<Constant *> Init;
  38. Constant *SwitchCase1BA = BlockAddress::get(SwitchCase1BB);
  39. Init.push_back(SwitchCase1BA);
  40. Constant *SwitchCase2BA = BlockAddress::get(SwitchCase2BB);
  41. Init.push_back(SwitchCase2BA);
  42. ConstantInt *One = ConstantInt::get(Type::getInt32Ty(Ctx), 1);
  43. Constant *OnePtr = ConstantExpr::getCast(Instruction::IntToPtr, One,
  44. Type::getInt8PtrTy(Ctx));
  45. Init.push_back(OnePtr);
  46. GV->setInitializer(ConstantArray::get(AT, Init));
  47. }
  48. void TearDown() override { M.reset(); }
  49. LLVMContext Ctx;
  50. std::unique_ptr<Module> M;
  51. Function *F;
  52. ArrayType *AT;
  53. GlobalVariable *GV;
  54. BasicBlock *EntryBB;
  55. BasicBlock *SwitchCase1BB;
  56. BasicBlock *SwitchCase2BB;
  57. BasicBlock *ExitBB;
  58. };
  59. TEST_F(LinkModuleTest, BlockAddress) {
  60. IRBuilder<> Builder(EntryBB);
  61. std::vector<Value *> GEPIndices;
  62. GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
  63. GEPIndices.push_back(F->arg_begin());
  64. Value *GEP = Builder.CreateGEP(AT, GV, GEPIndices, "switch.gep");
  65. Value *Load = Builder.CreateLoad(GEP, "switch.load");
  66. Builder.CreateRet(Load);
  67. Builder.SetInsertPoint(SwitchCase1BB);
  68. Builder.CreateBr(ExitBB);
  69. Builder.SetInsertPoint(SwitchCase2BB);
  70. Builder.CreateBr(ExitBB);
  71. Builder.SetInsertPoint(ExitBB);
  72. Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
  73. Module *LinkedModule = new Module("MyModuleLinked", Ctx);
  74. Linker::LinkModules(LinkedModule, M.get());
  75. // Delete the original module.
  76. M.reset();
  77. // Check that the global "@switch.bas" is well-formed.
  78. const GlobalVariable *LinkedGV = LinkedModule->getNamedGlobal("switch.bas");
  79. const Constant *Init = LinkedGV->getInitializer();
  80. // @switch.bas = internal global [3 x i8*]
  81. // [i8* blockaddress(@ba_func, %switch.case.1),
  82. // i8* blockaddress(@ba_func, %switch.case.2),
  83. // i8* inttoptr (i32 1 to i8*)]
  84. ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
  85. EXPECT_EQ(AT, Init->getType());
  86. Value *Elem = Init->getOperand(0);
  87. ASSERT_TRUE(isa<BlockAddress>(Elem));
  88. EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
  89. LinkedModule->getFunction("ba_func"));
  90. EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
  91. LinkedModule->getFunction("ba_func"));
  92. Elem = Init->getOperand(1);
  93. ASSERT_TRUE(isa<BlockAddress>(Elem));
  94. EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
  95. LinkedModule->getFunction("ba_func"));
  96. EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
  97. LinkedModule->getFunction("ba_func"));
  98. delete LinkedModule;
  99. }
  100. static Module *getExternal(LLVMContext &Ctx, StringRef FuncName) {
  101. // Create a module with an empty externally-linked function
  102. Module *M = new Module("ExternalModule", Ctx);
  103. FunctionType *FTy = FunctionType::get(
  104. Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
  105. Function *F =
  106. Function::Create(FTy, Function::ExternalLinkage, FuncName, M);
  107. F->setCallingConv(CallingConv::C);
  108. BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
  109. IRBuilder<> Builder(BB);
  110. Builder.CreateRetVoid();
  111. return M;
  112. }
  113. static Module *getInternal(LLVMContext &Ctx) {
  114. Module *InternalM = new Module("InternalModule", Ctx);
  115. FunctionType *FTy = FunctionType::get(
  116. Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
  117. Function *F =
  118. Function::Create(FTy, Function::InternalLinkage, "bar", InternalM);
  119. F->setCallingConv(CallingConv::C);
  120. BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
  121. IRBuilder<> Builder(BB);
  122. Builder.CreateRetVoid();
  123. StructType *STy = StructType::create(Ctx, PointerType::get(FTy, 0));
  124. GlobalVariable *GV =
  125. new GlobalVariable(*InternalM, STy, false /*=isConstant*/,
  126. GlobalValue::InternalLinkage, nullptr, "g");
  127. GV->setInitializer(ConstantStruct::get(STy, F));
  128. return InternalM;
  129. }
  130. TEST_F(LinkModuleTest, EmptyModule) {
  131. std::unique_ptr<Module> InternalM(getInternal(Ctx));
  132. std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
  133. Linker::LinkModules(EmptyM.get(), InternalM.get());
  134. }
  135. TEST_F(LinkModuleTest, EmptyModule2) {
  136. std::unique_ptr<Module> InternalM(getInternal(Ctx));
  137. std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
  138. Linker::LinkModules(InternalM.get(), EmptyM.get());
  139. }
  140. TEST_F(LinkModuleTest, TypeMerge) {
  141. LLVMContext C;
  142. SMDiagnostic Err;
  143. const char *M1Str = "%t = type {i32}\n"
  144. "@t1 = weak global %t zeroinitializer\n";
  145. std::unique_ptr<Module> M1 = parseAssemblyString(M1Str, Err, C);
  146. const char *M2Str = "%t = type {i32}\n"
  147. "@t2 = weak global %t zeroinitializer\n";
  148. std::unique_ptr<Module> M2 = parseAssemblyString(M2Str, Err, C);
  149. Linker::LinkModules(M1.get(), M2.get(), [](const llvm::DiagnosticInfo &){});
  150. EXPECT_EQ(M1->getNamedGlobal("t1")->getType(),
  151. M1->getNamedGlobal("t2")->getType());
  152. }
  153. TEST_F(LinkModuleTest, CAPISuccess) {
  154. std::unique_ptr<Module> DestM(getExternal(Ctx, "foo"));
  155. std::unique_ptr<Module> SourceM(getExternal(Ctx, "bar"));
  156. char *errout = nullptr;
  157. LLVMBool result = LLVMLinkModules(wrap(DestM.get()), wrap(SourceM.get()),
  158. LLVMLinkerDestroySource, &errout);
  159. EXPECT_EQ(0, result);
  160. EXPECT_EQ(nullptr, errout);
  161. // "bar" is present in destination module
  162. EXPECT_NE(nullptr, DestM->getFunction("bar"));
  163. }
  164. TEST_F(LinkModuleTest, CAPIFailure) {
  165. // Symbol clash between two modules
  166. std::unique_ptr<Module> DestM(getExternal(Ctx, "foo"));
  167. std::unique_ptr<Module> SourceM(getExternal(Ctx, "foo"));
  168. char *errout = nullptr;
  169. LLVMBool result = LLVMLinkModules(wrap(DestM.get()), wrap(SourceM.get()),
  170. LLVMLinkerDestroySource, &errout);
  171. EXPECT_EQ(1, result);
  172. EXPECT_STREQ("Linking globals named 'foo': symbol multiply defined!", errout);
  173. LLVMDisposeMessage(errout);
  174. }
  175. } // end anonymous namespace