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