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 9 #include "llvm/IR/Verifier.h" 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/IRBuilder.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/IR/Module.h" 20 #include "gtest/gtest.h" 21 22 namespace llvm { 23 namespace { 24 25 TEST(VerifierTest, Branch_i1) { 26 LLVMContext C; 27 Module M("M", C); 28 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); 29 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M); 30 BasicBlock *Entry = BasicBlock::Create(C, "entry", F); 31 BasicBlock *Exit = BasicBlock::Create(C, "exit", F); 32 ReturnInst::Create(C, Exit); 33 34 // To avoid triggering an assertion in BranchInst::Create, we first create 35 // a branch with an 'i1' condition ... 36 37 Constant *False = ConstantInt::getFalse(C); 38 BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry); 39 40 // ... then use setOperand to redirect it to a value of different type. 41 42 Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0); 43 BI->setOperand(0, Zero32); 44 45 EXPECT_TRUE(verifyFunction(*F)); 46 } 47 48 TEST(VerifierTest, Freeze) { 49 LLVMContext C; 50 Module M("M", C); 51 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); 52 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M); 53 BasicBlock *Entry = BasicBlock::Create(C, "entry", F); 54 ReturnInst *RI = ReturnInst::Create(C, Entry); 55 56 IntegerType *ITy = IntegerType::get(C, 32); 57 ConstantInt *CI = ConstantInt::get(ITy, 0); 58 59 // Valid type : freeze(<2 x i32>) 60 Constant *CV = ConstantVector::getSplat(ElementCount::getFixed(2), CI); 61 FreezeInst *FI_vec = new FreezeInst(CV); 62 FI_vec->insertBefore(RI); 63 64 EXPECT_FALSE(verifyFunction(*F)); 65 66 FI_vec->eraseFromParent(); 67 68 // Valid type : freeze(float) 69 Constant *CFP = ConstantFP::get(Type::getDoubleTy(C), 0.0); 70 FreezeInst *FI_dbl = new FreezeInst(CFP); 71 FI_dbl->insertBefore(RI); 72 73 EXPECT_FALSE(verifyFunction(*F)); 74 75 FI_dbl->eraseFromParent(); 76 77 // Valid type : freeze(i32*) 78 PointerType *PT = PointerType::get(ITy, 0); 79 ConstantPointerNull *CPN = ConstantPointerNull::get(PT); 80 FreezeInst *FI_ptr = new FreezeInst(CPN); 81 FI_ptr->insertBefore(RI); 82 83 EXPECT_FALSE(verifyFunction(*F)); 84 85 FI_ptr->eraseFromParent(); 86 87 // Valid type : freeze(int) 88 FreezeInst *FI = new FreezeInst(CI); 89 FI->insertBefore(RI); 90 91 EXPECT_FALSE(verifyFunction(*F)); 92 93 FI->eraseFromParent(); 94 } 95 96 TEST(VerifierTest, InvalidRetAttribute) { 97 LLVMContext C; 98 Module M("M", C); 99 FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); 100 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M); 101 AttributeList AS = F->getAttributes(); 102 F->setAttributes(AS.addRetAttribute(C, Attribute::UWTable)); 103 104 std::string Error; 105 raw_string_ostream ErrorOS(Error); 106 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 107 EXPECT_TRUE(StringRef(ErrorOS.str()).startswith( 108 "Attribute 'uwtable' does not apply to function return values")); 109 } 110 111 TEST(VerifierTest, CrossModuleRef) { 112 LLVMContext C; 113 Module M1("M1", C); 114 Module M2("M2", C); 115 Module M3("M3", C); 116 FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); 117 Function *F1 = Function::Create(FTy, Function::ExternalLinkage, "foo1", M1); 118 Function *F2 = Function::Create(FTy, Function::ExternalLinkage, "foo2", M2); 119 Function *F3 = Function::Create(FTy, Function::ExternalLinkage, "foo3", M3); 120 121 BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1); 122 BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3); 123 124 // BAD: Referencing function in another module 125 CallInst::Create(F2,"call",Entry1); 126 127 // BAD: Referencing personality routine in another module 128 F3->setPersonalityFn(F2); 129 130 // Fill in the body 131 Constant *ConstZero = ConstantInt::get(Type::getInt32Ty(C), 0); 132 ReturnInst::Create(C, ConstZero, Entry1); 133 ReturnInst::Create(C, ConstZero, Entry3); 134 135 std::string Error; 136 raw_string_ostream ErrorOS(Error); 137 EXPECT_TRUE(verifyModule(M2, &ErrorOS)); 138 EXPECT_TRUE(StringRef(ErrorOS.str()) 139 .equals("Global is referenced in a different module!\n" 140 "i32 ()* @foo2\n" 141 "; ModuleID = 'M2'\n" 142 " %call = call i32 @foo2()\n" 143 "i32 ()* @foo1\n" 144 "; ModuleID = 'M1'\n" 145 "Global is used by function in a different module\n" 146 "i32 ()* @foo2\n" 147 "; ModuleID = 'M2'\n" 148 "i32 ()* @foo3\n" 149 "; ModuleID = 'M3'\n")); 150 151 Error.clear(); 152 EXPECT_TRUE(verifyModule(M1, &ErrorOS)); 153 EXPECT_TRUE(StringRef(ErrorOS.str()).equals( 154 "Referencing function in another module!\n" 155 " %call = call i32 @foo2()\n" 156 "; ModuleID = 'M1'\n" 157 "i32 ()* @foo2\n" 158 "; ModuleID = 'M2'\n")); 159 160 Error.clear(); 161 EXPECT_TRUE(verifyModule(M3, &ErrorOS)); 162 EXPECT_TRUE(StringRef(ErrorOS.str()).startswith( 163 "Referencing personality function in another module!")); 164 165 // Erase bad methods to avoid triggering an assertion failure on destruction 166 F1->eraseFromParent(); 167 F3->eraseFromParent(); 168 } 169 170 TEST(VerifierTest, InvalidVariableLinkage) { 171 LLVMContext C; 172 Module M("M", C); 173 new GlobalVariable(M, Type::getInt8Ty(C), false, 174 GlobalValue::LinkOnceODRLinkage, nullptr, "Some Global"); 175 std::string Error; 176 raw_string_ostream ErrorOS(Error); 177 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 178 EXPECT_TRUE( 179 StringRef(ErrorOS.str()).startswith("Global is external, but doesn't " 180 "have external or weak linkage!")); 181 } 182 183 TEST(VerifierTest, InvalidFunctionLinkage) { 184 LLVMContext C; 185 Module M("M", C); 186 187 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false); 188 Function::Create(FTy, GlobalValue::LinkOnceODRLinkage, "foo", &M); 189 std::string Error; 190 raw_string_ostream ErrorOS(Error); 191 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 192 EXPECT_TRUE( 193 StringRef(ErrorOS.str()).startswith("Global is external, but doesn't " 194 "have external or weak linkage!")); 195 } 196 197 TEST(VerifierTest, DetectInvalidDebugInfo) { 198 { 199 LLVMContext C; 200 Module M("M", C); 201 DIBuilder DIB(M); 202 DIB.createCompileUnit(dwarf::DW_LANG_C89, DIB.createFile("broken.c", "/"), 203 "unittest", false, "", 0); 204 DIB.finalize(); 205 EXPECT_FALSE(verifyModule(M)); 206 207 // Now break it by inserting non-CU node to the list of CUs. 208 auto *File = DIB.createFile("not-a-CU.f", "."); 209 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); 210 NMD->addOperand(File); 211 EXPECT_TRUE(verifyModule(M)); 212 } 213 { 214 LLVMContext C; 215 Module M("M", C); 216 DIBuilder DIB(M); 217 auto *CU = DIB.createCompileUnit(dwarf::DW_LANG_C89, 218 DIB.createFile("broken.c", "/"), 219 "unittest", false, "", 0); 220 new GlobalVariable(M, Type::getInt8Ty(C), false, 221 GlobalValue::ExternalLinkage, nullptr, "g"); 222 223 auto *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false), 224 Function::ExternalLinkage, "f", M); 225 IRBuilder<> Builder(BasicBlock::Create(C, "", F)); 226 Builder.CreateUnreachable(); 227 F->setSubprogram(DIB.createFunction( 228 CU, "f", "f", DIB.createFile("broken.c", "/"), 1, nullptr, 1, 229 DINode::FlagZero, 230 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition)); 231 DIB.finalize(); 232 EXPECT_FALSE(verifyModule(M)); 233 234 // Now break it by not listing the CU at all. 235 M.eraseNamedMetadata(M.getOrInsertNamedMetadata("llvm.dbg.cu")); 236 EXPECT_TRUE(verifyModule(M)); 237 } 238 } 239 240 TEST(VerifierTest, MDNodeWrongContext) { 241 LLVMContext C1, C2; 242 auto *Node = MDNode::get(C1, None); 243 244 Module M("M", C2); 245 auto *NamedNode = M.getOrInsertNamedMetadata("test"); 246 NamedNode->addOperand(Node); 247 248 std::string Error; 249 raw_string_ostream ErrorOS(Error); 250 EXPECT_TRUE(verifyModule(M, &ErrorOS)); 251 EXPECT_TRUE(StringRef(ErrorOS.str()) 252 .startswith("MDNode context does not match Module context!")); 253 } 254 255 TEST(VerifierTest, AttributesWrongContext) { 256 LLVMContext C1, C2; 257 Module M1("M", C1); 258 FunctionType *FTy1 = 259 FunctionType::get(Type::getVoidTy(C1), /*isVarArg=*/false); 260 Function *F1 = Function::Create(FTy1, Function::ExternalLinkage, "foo", M1); 261 F1->setDoesNotReturn(); 262 263 Module M2("M", C2); 264 FunctionType *FTy2 = 265 FunctionType::get(Type::getVoidTy(C2), /*isVarArg=*/false); 266 Function *F2 = Function::Create(FTy2, Function::ExternalLinkage, "foo", M2); 267 F2->copyAttributesFrom(F1); 268 269 EXPECT_TRUE(verifyFunction(*F2)); 270 } 271 272 } // end anonymous namespace 273 } // end namespace llvm 274