VerifierTest.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. //===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/IR/Verifier.h"
  9. #include "llvm/IR/Constants.h"
  10. #include "llvm/IR/DIBuilder.h"
  11. #include "llvm/IR/DerivedTypes.h"
  12. #include "llvm/IR/Function.h"
  13. #include "llvm/IR/GlobalAlias.h"
  14. #include "llvm/IR/GlobalVariable.h"
  15. #include "llvm/IR/IRBuilder.h"
  16. #include "llvm/IR/Instructions.h"
  17. #include "llvm/IR/LLVMContext.h"
  18. #include "llvm/IR/Module.h"
  19. #include "gtest/gtest.h"
  20. namespace llvm {
  21. namespace {
  22. TEST(VerifierTest, Branch_i1) {
  23. LLVMContext C;
  24. Module M("M", C);
  25. FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
  26. Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
  27. BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
  28. BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
  29. ReturnInst::Create(C, Exit);
  30. // To avoid triggering an assertion in BranchInst::Create, we first create
  31. // a branch with an 'i1' condition ...
  32. Constant *False = ConstantInt::getFalse(C);
  33. BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry);
  34. // ... then use setOperand to redirect it to a value of different type.
  35. Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
  36. BI->setOperand(0, Zero32);
  37. EXPECT_TRUE(verifyFunction(*F));
  38. }
  39. TEST(VerifierTest, InvalidRetAttribute) {
  40. LLVMContext C;
  41. Module M("M", C);
  42. FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
  43. Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
  44. AttributeList AS = F->getAttributes();
  45. F->setAttributes(
  46. AS.addAttribute(C, AttributeList::ReturnIndex, Attribute::UWTable));
  47. std::string Error;
  48. raw_string_ostream ErrorOS(Error);
  49. EXPECT_TRUE(verifyModule(M, &ErrorOS));
  50. EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
  51. "Attribute 'uwtable' only applies to functions!"));
  52. }
  53. TEST(VerifierTest, CrossModuleRef) {
  54. LLVMContext C;
  55. Module M1("M1", C);
  56. Module M2("M2", C);
  57. Module M3("M3", C);
  58. FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
  59. Function *F1 = Function::Create(FTy, Function::ExternalLinkage, "foo1", M1);
  60. Function *F2 = Function::Create(FTy, Function::ExternalLinkage, "foo2", M2);
  61. Function *F3 = Function::Create(FTy, Function::ExternalLinkage, "foo3", M3);
  62. BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1);
  63. BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3);
  64. // BAD: Referencing function in another module
  65. CallInst::Create(F2,"call",Entry1);
  66. // BAD: Referencing personality routine in another module
  67. F3->setPersonalityFn(F2);
  68. // Fill in the body
  69. Constant *ConstZero = ConstantInt::get(Type::getInt32Ty(C), 0);
  70. ReturnInst::Create(C, ConstZero, Entry1);
  71. ReturnInst::Create(C, ConstZero, Entry3);
  72. std::string Error;
  73. raw_string_ostream ErrorOS(Error);
  74. EXPECT_TRUE(verifyModule(M2, &ErrorOS));
  75. EXPECT_TRUE(StringRef(ErrorOS.str())
  76. .equals("Global is used by function in a different module\n"
  77. "i32 ()* @foo2\n"
  78. "; ModuleID = 'M2'\n"
  79. "i32 ()* @foo3\n"
  80. "; ModuleID = 'M3'\n"
  81. "Global is referenced in a different module!\n"
  82. "i32 ()* @foo2\n"
  83. "; ModuleID = 'M2'\n"
  84. " %call = call i32 @foo2()\n"
  85. "i32 ()* @foo1\n"
  86. "; ModuleID = 'M1'\n"));
  87. Error.clear();
  88. EXPECT_TRUE(verifyModule(M1, &ErrorOS));
  89. EXPECT_TRUE(StringRef(ErrorOS.str()).equals(
  90. "Referencing function in another module!\n"
  91. " %call = call i32 @foo2()\n"
  92. "; ModuleID = 'M1'\n"
  93. "i32 ()* @foo2\n"
  94. "; ModuleID = 'M2'\n"));
  95. Error.clear();
  96. EXPECT_TRUE(verifyModule(M3, &ErrorOS));
  97. EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
  98. "Referencing personality function in another module!"));
  99. // Erase bad methods to avoid triggering an assertion failure on destruction
  100. F1->eraseFromParent();
  101. F3->eraseFromParent();
  102. }
  103. TEST(VerifierTest, InvalidVariableLinkage) {
  104. LLVMContext C;
  105. Module M("M", C);
  106. new GlobalVariable(M, Type::getInt8Ty(C), false,
  107. GlobalValue::LinkOnceODRLinkage, nullptr, "Some Global");
  108. std::string Error;
  109. raw_string_ostream ErrorOS(Error);
  110. EXPECT_TRUE(verifyModule(M, &ErrorOS));
  111. EXPECT_TRUE(
  112. StringRef(ErrorOS.str()).startswith("Global is external, but doesn't "
  113. "have external or weak linkage!"));
  114. }
  115. TEST(VerifierTest, InvalidFunctionLinkage) {
  116. LLVMContext C;
  117. Module M("M", C);
  118. FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
  119. Function::Create(FTy, GlobalValue::LinkOnceODRLinkage, "foo", &M);
  120. std::string Error;
  121. raw_string_ostream ErrorOS(Error);
  122. EXPECT_TRUE(verifyModule(M, &ErrorOS));
  123. EXPECT_TRUE(
  124. StringRef(ErrorOS.str()).startswith("Global is external, but doesn't "
  125. "have external or weak linkage!"));
  126. }
  127. TEST(VerifierTest, DetectInvalidDebugInfo) {
  128. {
  129. LLVMContext C;
  130. Module M("M", C);
  131. DIBuilder DIB(M);
  132. DIB.createCompileUnit(dwarf::DW_LANG_C89, DIB.createFile("broken.c", "/"),
  133. "unittest", false, "", 0);
  134. DIB.finalize();
  135. EXPECT_FALSE(verifyModule(M));
  136. // Now break it by inserting non-CU node to the list of CUs.
  137. auto *File = DIB.createFile("not-a-CU.f", ".");
  138. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
  139. NMD->addOperand(File);
  140. EXPECT_TRUE(verifyModule(M));
  141. }
  142. {
  143. LLVMContext C;
  144. Module M("M", C);
  145. DIBuilder DIB(M);
  146. auto *CU = DIB.createCompileUnit(dwarf::DW_LANG_C89,
  147. DIB.createFile("broken.c", "/"),
  148. "unittest", false, "", 0);
  149. new GlobalVariable(M, Type::getInt8Ty(C), false,
  150. GlobalValue::ExternalLinkage, nullptr, "g");
  151. auto *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
  152. Function::ExternalLinkage, "f", M);
  153. IRBuilder<> Builder(BasicBlock::Create(C, "", F));
  154. Builder.CreateUnreachable();
  155. F->setSubprogram(DIB.createFunction(
  156. CU, "f", "f", DIB.createFile("broken.c", "/"), 1, nullptr, 1,
  157. DINode::FlagZero,
  158. DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition));
  159. DIB.finalize();
  160. EXPECT_FALSE(verifyModule(M));
  161. // Now break it by not listing the CU at all.
  162. M.eraseNamedMetadata(M.getOrInsertNamedMetadata("llvm.dbg.cu"));
  163. EXPECT_TRUE(verifyModule(M));
  164. }
  165. }
  166. } // end anonymous namespace
  167. } // end namespace llvm