1 //===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===// 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 10 #include "llvm/IR/Constants.h" 11 #include "llvm/IR/DIBuilder.h" 12 #include "llvm/IR/DerivedTypes.h" 13 #include "llvm/IR/Function.h" 14 #include "llvm/IR/GlobalAlias.h" 15 #include "llvm/IR/GlobalVariable.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/IRBuilder.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/IR/LegacyPassManager.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/Verifier.h" 22 #include "gtest/gtest.h" 23 24 namespace llvm { 25 namespace { 26 27 TEST(VerifierTest, Branch_i1) { 28 LLVMContext C; 29 Module M("M", C); 30 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); 31 Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy)); 32 BasicBlock *Entry = BasicBlock::Create(C, "entry", F); 33 BasicBlock *Exit = BasicBlock::Create(C, "exit", F); 34 ReturnInst::Create(C, Exit); 35 36 // To avoid triggering an assertion in BranchInst::Create, we first create 37 // a branch with an 'i1' condition ... 38 39 Constant *False = ConstantInt::getFalse(C); 40 BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry); 41 42 // ... then use setOperand to redirect it to a value of different type. 43 44 Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0); 45 BI->setOperand(0, Zero32); 46 47 EXPECT_TRUE(verifyFunction(*F)); 48 } 49 50 TEST(VerifierTest, InvalidRetAttribute) { 51 LLVMContext C; 52 Module M("M", C); 53 FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); 54 Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy)); 55 AttributeSet AS = F->getAttributes(); 56 F->setAttributes(AS.addAttribute(C, AttributeSet::ReturnIndex, 57 Attribute::UWTable)); 58 59 std::string Error; 60 raw_string_ostream ErrorOS(Error); 61 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 62 EXPECT_TRUE(StringRef(ErrorOS.str()).startswith( 63 "Attribute 'uwtable' only applies to functions!")); 64 } 65 66 TEST(VerifierTest, CrossModuleRef) { 67 LLVMContext C; 68 Module M1("M1", C); 69 Module M2("M2", C); 70 Module M3("M3", C); 71 FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); 72 Function *F1 = cast<Function>(M1.getOrInsertFunction("foo1", FTy)); 73 Function *F2 = cast<Function>(M2.getOrInsertFunction("foo2", FTy)); 74 Function *F3 = cast<Function>(M3.getOrInsertFunction("foo3", FTy)); 75 76 BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1); 77 BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3); 78 79 // BAD: Referencing function in another module 80 CallInst::Create(F2,"call",Entry1); 81 82 // BAD: Referencing personality routine in another module 83 F3->setPersonalityFn(F2); 84 85 // Fill in the body 86 Constant *ConstZero = ConstantInt::get(Type::getInt32Ty(C), 0); 87 ReturnInst::Create(C, ConstZero, Entry1); 88 ReturnInst::Create(C, ConstZero, Entry3); 89 90 std::string Error; 91 raw_string_ostream ErrorOS(Error); 92 EXPECT_TRUE(verifyModule(M2, &ErrorOS)); 93 EXPECT_TRUE(StringRef(ErrorOS.str()) 94 .equals("Global is used by function in a different module\n" 95 "i32 ()* @foo2\n" 96 "; ModuleID = 'M2'\n" 97 "i32 ()* @foo3\n" 98 "; ModuleID = 'M3'\n" 99 "Global is referenced in a different module!\n" 100 "i32 ()* @foo2\n" 101 "; ModuleID = 'M2'\n" 102 " %call = call i32 @foo2()\n" 103 "i32 ()* @foo1\n" 104 "; ModuleID = 'M1'\n")); 105 106 Error.clear(); 107 EXPECT_TRUE(verifyModule(M1, &ErrorOS)); 108 EXPECT_TRUE(StringRef(ErrorOS.str()).equals( 109 "Referencing function in another module!\n" 110 " %call = call i32 @foo2()\n" 111 "; ModuleID = 'M1'\n" 112 "i32 ()* @foo2\n" 113 "; ModuleID = 'M2'\n")); 114 115 Error.clear(); 116 EXPECT_TRUE(verifyModule(M3, &ErrorOS)); 117 EXPECT_TRUE(StringRef(ErrorOS.str()).startswith( 118 "Referencing personality function in another module!")); 119 120 // Erase bad methods to avoid triggering an assertion failure on destruction 121 F1->eraseFromParent(); 122 F3->eraseFromParent(); 123 } 124 125 TEST(VerifierTest, InvalidVariableLinkage) { 126 LLVMContext C; 127 Module M("M", C); 128 new GlobalVariable(M, Type::getInt8Ty(C), false, 129 GlobalValue::LinkOnceODRLinkage, nullptr, "Some Global"); 130 std::string Error; 131 raw_string_ostream ErrorOS(Error); 132 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 133 EXPECT_TRUE( 134 StringRef(ErrorOS.str()).startswith("Global is external, but doesn't " 135 "have external or weak linkage!")); 136 } 137 138 TEST(VerifierTest, InvalidFunctionLinkage) { 139 LLVMContext C; 140 Module M("M", C); 141 142 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); 143 Function::Create(FTy, GlobalValue::LinkOnceODRLinkage, "foo", &M); 144 std::string Error; 145 raw_string_ostream ErrorOS(Error); 146 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 147 EXPECT_TRUE( 148 StringRef(ErrorOS.str()).startswith("Global is external, but doesn't " 149 "have external or weak linkage!")); 150 } 151 152 TEST(VerifierTest, StripInvalidDebugInfo) { 153 { 154 LLVMContext C; 155 Module M("M", C); 156 DIBuilder DIB(M); 157 DIB.createCompileUnit(dwarf::DW_LANG_C89, DIB.createFile("broken.c", "/"), 158 "unittest", false, "", 0); 159 DIB.finalize(); 160 EXPECT_FALSE(verifyModule(M)); 161 162 // Now break it by inserting non-CU node to the list of CUs. 163 auto *File = DIB.createFile("not-a-CU.f", "."); 164 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); 165 NMD->addOperand(File); 166 EXPECT_TRUE(verifyModule(M)); 167 168 ModulePassManager MPM(true); 169 MPM.addPass(VerifierPass(false)); 170 ModuleAnalysisManager MAM(true); 171 MAM.registerPass([&] { return VerifierAnalysis(); }); 172 MPM.run(M, MAM); 173 EXPECT_FALSE(verifyModule(M)); 174 } 175 { 176 LLVMContext C; 177 Module M("M", C); 178 DIBuilder DIB(M); 179 auto *CU = DIB.createCompileUnit(dwarf::DW_LANG_C89, 180 DIB.createFile("broken.c", "/"), 181 "unittest", false, "", 0); 182 new GlobalVariable(M, Type::getInt8Ty(C), false, 183 GlobalValue::ExternalLinkage, nullptr, "g"); 184 185 auto *F = cast<Function>(M.getOrInsertFunction( 186 "f", FunctionType::get(Type::getVoidTy(C), false))); 187 IRBuilder<> Builder(BasicBlock::Create(C, "", F)); 188 Builder.CreateUnreachable(); 189 F->setSubprogram(DIB.createFunction(CU, "f", "f", 190 DIB.createFile("broken.c", "/"), 1, 191 nullptr, true, true, 1)); 192 DIB.finalize(); 193 EXPECT_FALSE(verifyModule(M)); 194 195 // Now break it by not listing the CU at all. 196 M.eraseNamedMetadata(M.getOrInsertNamedMetadata("llvm.dbg.cu")); 197 EXPECT_TRUE(verifyModule(M)); 198 199 ModulePassManager MPM(true); 200 MPM.addPass(VerifierPass(false)); 201 ModuleAnalysisManager MAM(true); 202 MAM.registerPass([&] { return VerifierAnalysis(); }); 203 MPM.run(M, MAM); 204 EXPECT_FALSE(verifyModule(M)); 205 } 206 } 207 208 TEST(VerifierTest, StripInvalidDebugInfoLegacy) { 209 LLVMContext C; 210 Module M("M", C); 211 DIBuilder DIB(M); 212 DIB.createCompileUnit(dwarf::DW_LANG_C89, DIB.createFile("broken.c", "/"), 213 "unittest", false, "", 0); 214 DIB.finalize(); 215 EXPECT_FALSE(verifyModule(M)); 216 217 // Now break it. 218 auto *File = DIB.createFile("not-a-CU.f", "."); 219 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); 220 NMD->addOperand(File); 221 EXPECT_TRUE(verifyModule(M)); 222 223 legacy::PassManager Passes; 224 Passes.add(createVerifierPass(false)); 225 Passes.run(M); 226 EXPECT_FALSE(verifyModule(M)); 227 } 228 229 } // end anonymous namespace 230 } // end namespace llvm 231