1 //===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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/GlobalValue.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"
26 TEST(VerifierTest
, Branch_i1
) {
29 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), /*isVarArg=*/false);
30 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
31 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
32 BasicBlock
*Exit
= BasicBlock::Create(C
, "exit", F
);
33 ReturnInst::Create(C
, Exit
);
35 // To avoid triggering an assertion in BranchInst::Create, we first create
36 // a branch with an 'i1' condition ...
38 Constant
*False
= ConstantInt::getFalse(C
);
39 BranchInst
*BI
= BranchInst::Create(Exit
, Exit
, False
, Entry
);
41 // ... then use setOperand to redirect it to a value of different type.
43 Constant
*Zero32
= ConstantInt::get(IntegerType::get(C
, 32), 0);
44 BI
->setOperand(0, Zero32
);
46 EXPECT_TRUE(verifyFunction(*F
));
49 TEST(VerifierTest
, Freeze
) {
52 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), /*isVarArg=*/false);
53 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
54 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
55 ReturnInst
*RI
= ReturnInst::Create(C
, Entry
);
57 IntegerType
*ITy
= IntegerType::get(C
, 32);
58 ConstantInt
*CI
= ConstantInt::get(ITy
, 0);
60 // Valid type : freeze(<2 x i32>)
61 Constant
*CV
= ConstantVector::getSplat(ElementCount::getFixed(2), CI
);
62 FreezeInst
*FI_vec
= new FreezeInst(CV
);
63 FI_vec
->insertBefore(RI
);
65 EXPECT_FALSE(verifyFunction(*F
));
67 FI_vec
->eraseFromParent();
69 // Valid type : freeze(float)
70 Constant
*CFP
= ConstantFP::get(Type::getDoubleTy(C
), 0.0);
71 FreezeInst
*FI_dbl
= new FreezeInst(CFP
);
72 FI_dbl
->insertBefore(RI
);
74 EXPECT_FALSE(verifyFunction(*F
));
76 FI_dbl
->eraseFromParent();
78 // Valid type : freeze(i32*)
79 PointerType
*PT
= PointerType::get(ITy
, 0);
80 ConstantPointerNull
*CPN
= ConstantPointerNull::get(PT
);
81 FreezeInst
*FI_ptr
= new FreezeInst(CPN
);
82 FI_ptr
->insertBefore(RI
);
84 EXPECT_FALSE(verifyFunction(*F
));
86 FI_ptr
->eraseFromParent();
88 // Valid type : freeze(int)
89 FreezeInst
*FI
= new FreezeInst(CI
);
92 EXPECT_FALSE(verifyFunction(*F
));
94 FI
->eraseFromParent();
97 TEST(VerifierTest
, InvalidRetAttribute
) {
100 FunctionType
*FTy
= FunctionType::get(Type::getInt32Ty(C
), /*isVarArg=*/false);
101 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
102 AttributeList AS
= F
->getAttributes();
103 F
->setAttributes(AS
.addRetAttribute(
104 C
, Attribute::getWithUWTableKind(C
, UWTableKind::Default
)));
107 raw_string_ostream
ErrorOS(Error
);
108 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
109 EXPECT_TRUE(StringRef(Error
).starts_with(
110 "Attribute 'uwtable' does not apply to function return values"));
113 /// Test the verifier rejects invalid nofpclass values that the assembler may
114 /// also choose to reject.
115 TEST(VerifierTest
, InvalidNoFPClassAttribute
) {
118 const unsigned InvalidMasks
[] = {0, fcAllFlags
+ 1};
120 for (unsigned InvalidMask
: InvalidMasks
) {
123 FunctionType::get(Type::getFloatTy(C
), /*isVarArg=*/false);
124 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
125 AttributeList AS
= F
->getAttributes();
127 // Don't use getWithNoFPClass to avoid using out of bounds enum values here.
128 F
->setAttributes(AS
.addRetAttribute(
129 C
, Attribute::get(C
, Attribute::NoFPClass
, InvalidMask
)));
132 raw_string_ostream
ErrorOS(Error
);
133 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
135 StringRef
ErrMsg(Error
);
137 if (InvalidMask
== 0) {
138 EXPECT_TRUE(ErrMsg
.starts_with(
139 "Attribute 'nofpclass' must have at least one test bit set"))
142 EXPECT_TRUE(ErrMsg
.starts_with("Invalid value for 'nofpclass' test mask"))
148 TEST(VerifierTest
, CrossModuleRef
) {
153 FunctionType
*FTy
= FunctionType::get(Type::getInt32Ty(C
), /*isVarArg=*/false);
154 Function
*F1
= Function::Create(FTy
, Function::ExternalLinkage
, "foo1", M1
);
155 Function
*F2
= Function::Create(FTy
, Function::ExternalLinkage
, "foo2", M2
);
156 Function
*F3
= Function::Create(FTy
, Function::ExternalLinkage
, "foo3", M3
);
158 BasicBlock
*Entry1
= BasicBlock::Create(C
, "entry", F1
);
159 BasicBlock
*Entry3
= BasicBlock::Create(C
, "entry", F3
);
161 // BAD: Referencing function in another module
162 CallInst::Create(F2
,"call",Entry1
);
164 // BAD: Referencing personality routine in another module
165 F3
->setPersonalityFn(F2
);
168 Constant
*ConstZero
= ConstantInt::get(Type::getInt32Ty(C
), 0);
169 ReturnInst::Create(C
, ConstZero
, Entry1
);
170 ReturnInst::Create(C
, ConstZero
, Entry3
);
173 raw_string_ostream
ErrorOS(Error
);
174 EXPECT_TRUE(verifyModule(M2
, &ErrorOS
));
175 EXPECT_TRUE(Error
== "Global is referenced in a different module!\n"
177 "; ModuleID = 'M2'\n"
178 " %call = call i32 @foo2()\n"
180 "; ModuleID = 'M1'\n"
181 "Global is used by function in a different module\n"
183 "; ModuleID = 'M2'\n"
185 "; ModuleID = 'M3'\n");
188 EXPECT_TRUE(verifyModule(M1
, &ErrorOS
));
189 EXPECT_TRUE(StringRef(Error
) == "Referencing function in another module!\n"
190 " %call = call i32 @foo2()\n"
191 "; ModuleID = 'M1'\n"
193 "; ModuleID = 'M2'\n");
196 EXPECT_TRUE(verifyModule(M3
, &ErrorOS
));
197 EXPECT_TRUE(StringRef(Error
).starts_with(
198 "Referencing personality function in another module!"));
200 // Erase bad methods to avoid triggering an assertion failure on destruction
201 F1
->eraseFromParent();
202 F3
->eraseFromParent();
205 TEST(VerifierTest
, InvalidVariableLinkage
) {
208 new GlobalVariable(M
, Type::getInt8Ty(C
), false,
209 GlobalValue::LinkOnceODRLinkage
, nullptr, "Some Global");
211 raw_string_ostream
ErrorOS(Error
);
212 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
213 EXPECT_TRUE(StringRef(Error
).starts_with("Global is external, but doesn't "
214 "have external or weak linkage!"));
217 TEST(VerifierTest
, InvalidFunctionLinkage
) {
221 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), /*isVarArg=*/false);
222 Function::Create(FTy
, GlobalValue::LinkOnceODRLinkage
, "foo", &M
);
224 raw_string_ostream
ErrorOS(Error
);
225 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
226 EXPECT_TRUE(StringRef(Error
).starts_with("Global is external, but doesn't "
227 "have external or weak linkage!"));
230 TEST(VerifierTest
, DetectInvalidDebugInfo
) {
235 DIB
.createCompileUnit(dwarf::DW_LANG_C89
, DIB
.createFile("broken.c", "/"),
236 "unittest", false, "", 0);
238 EXPECT_FALSE(verifyModule(M
));
240 // Now break it by inserting non-CU node to the list of CUs.
241 auto *File
= DIB
.createFile("not-a-CU.f", ".");
242 NamedMDNode
*NMD
= M
.getOrInsertNamedMetadata("llvm.dbg.cu");
243 NMD
->addOperand(File
);
244 EXPECT_TRUE(verifyModule(M
));
250 auto *CU
= DIB
.createCompileUnit(dwarf::DW_LANG_C89
,
251 DIB
.createFile("broken.c", "/"),
252 "unittest", false, "", 0);
253 new GlobalVariable(M
, Type::getInt8Ty(C
), false,
254 GlobalValue::ExternalLinkage
, nullptr, "g");
256 auto *F
= Function::Create(FunctionType::get(Type::getVoidTy(C
), false),
257 Function::ExternalLinkage
, "f", M
);
258 IRBuilder
<> Builder(BasicBlock::Create(C
, "", F
));
259 Builder
.CreateUnreachable();
260 F
->setSubprogram(DIB
.createFunction(
261 CU
, "f", "f", DIB
.createFile("broken.c", "/"), 1, nullptr, 1,
263 DISubprogram::SPFlagLocalToUnit
| DISubprogram::SPFlagDefinition
));
265 EXPECT_FALSE(verifyModule(M
));
267 // Now break it by not listing the CU at all.
268 M
.eraseNamedMetadata(M
.getOrInsertNamedMetadata("llvm.dbg.cu"));
269 EXPECT_TRUE(verifyModule(M
));
273 TEST(VerifierTest
, MDNodeWrongContext
) {
275 auto *Node
= MDNode::get(C1
, {});
278 auto *NamedNode
= M
.getOrInsertNamedMetadata("test");
279 NamedNode
->addOperand(Node
);
282 raw_string_ostream
ErrorOS(Error
);
283 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
284 EXPECT_TRUE(StringRef(Error
).starts_with(
285 "MDNode context does not match Module context!"));
288 TEST(VerifierTest
, AttributesWrongContext
) {
292 FunctionType::get(Type::getVoidTy(C1
), /*isVarArg=*/false);
293 Function
*F1
= Function::Create(FTy1
, Function::ExternalLinkage
, "foo", M1
);
294 F1
->setDoesNotReturn();
298 FunctionType::get(Type::getVoidTy(C2
), /*isVarArg=*/false);
299 Function
*F2
= Function::Create(FTy2
, Function::ExternalLinkage
, "foo", M2
);
300 F2
->copyAttributesFrom(F1
);
302 EXPECT_TRUE(verifyFunction(*F2
));
305 TEST(VerifierTest
, SwitchInst
) {
308 IntegerType
*Int32Ty
= Type::getInt32Ty(C
);
309 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), {Int32Ty
, Int32Ty
},
311 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
312 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
313 BasicBlock
*Default
= BasicBlock::Create(C
, "default", F
);
314 BasicBlock
*OnOne
= BasicBlock::Create(C
, "on_one", F
);
315 BasicBlock
*OnTwo
= BasicBlock::Create(C
, "on_two", F
);
317 BasicBlock
*Exit
= BasicBlock::Create(C
, "exit", F
);
319 BranchInst::Create(Exit
, Default
);
320 BranchInst::Create(Exit
, OnTwo
);
321 BranchInst::Create(Exit
, OnOne
);
322 ReturnInst::Create(C
, Exit
);
324 Value
*Cond
= F
->getArg(0);
325 SwitchInst
*Switch
= SwitchInst::Create(Cond
, Default
, 2, Entry
);
326 Switch
->addCase(ConstantInt::get(Int32Ty
, 1), OnOne
);
327 Switch
->addCase(ConstantInt::get(Int32Ty
, 2), OnTwo
);
329 EXPECT_FALSE(verifyFunction(*F
));
330 // set one case value to function argument.
331 Switch
->setOperand(2, F
->getArg(1));
332 EXPECT_TRUE(verifyFunction(*F
));
335 TEST(VerifierTest
, CrossFunctionRef
) {
338 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), /*isVarArg=*/false);
339 Function
*F1
= Function::Create(FTy
, Function::ExternalLinkage
, "foo1", M
);
340 Function
*F2
= Function::Create(FTy
, Function::ExternalLinkage
, "foo2", M
);
341 BasicBlock
*Entry1
= BasicBlock::Create(C
, "entry", F1
);
342 BasicBlock
*Entry2
= BasicBlock::Create(C
, "entry", F2
);
343 Type
*I32
= Type::getInt32Ty(C
);
345 Value
*Alloca
= new AllocaInst(I32
, 0, "alloca", Entry1
);
346 ReturnInst::Create(C
, Entry1
);
348 Instruction
*Store
= new StoreInst(ConstantInt::get(I32
, 0), Alloca
, Entry2
);
349 ReturnInst::Create(C
, Entry2
);
352 raw_string_ostream
ErrorOS(Error
);
353 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
354 EXPECT_TRUE(StringRef(Error
).starts_with(
355 "Referring to an instruction in another function!"));
357 // Explicitly erase the store to avoid a use-after-free when the module is
359 Store
->eraseFromParent();
362 TEST(VerifierTest
, AtomicRMW
) {
365 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), /*isVarArg=*/false);
366 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
367 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
368 Value
*Ptr
= PoisonValue::get(PointerType::get(C
, 0));
370 Type
*FPTy
= Type::getFloatTy(C
);
371 Constant
*CF
= ConstantFP::getZero(FPTy
);
373 // Invalid scalable type : atomicrmw (<vscale x 2 x float>)
374 Constant
*CV
= ConstantVector::getSplat(ElementCount::getScalable(2), CF
);
375 new AtomicRMWInst(AtomicRMWInst::FAdd
, Ptr
, CV
, Align(8),
376 AtomicOrdering::SequentiallyConsistent
, SyncScope::System
,
378 ReturnInst::Create(C
, Entry
);
381 raw_string_ostream
ErrorOS(Error
);
382 EXPECT_TRUE(verifyFunction(*F
, &ErrorOS
));
383 EXPECT_TRUE(StringRef(Error
).starts_with(
384 "atomicrmw fadd operand must have floating-point or "
385 "fixed vector of floating-point type!"))
389 TEST(VerifierTest
, GetElementPtrInst
) {
392 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), /*isVarArg=*/false);
393 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
, "foo", M
);
394 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
395 ReturnInst
*RI
= ReturnInst::Create(C
, Entry
);
397 FixedVectorType
*V2P1Ty
= FixedVectorType::get(PointerType::get(C
, 1), 2);
398 FixedVectorType
*V2P2Ty
= FixedVectorType::get(PointerType::get(C
, 2), 2);
400 Instruction
*GEPVec
= GetElementPtrInst::Create(
401 Type::getInt8Ty(C
), ConstantAggregateZero::get(V2P1Ty
),
402 {ConstantVector::getSplat(ElementCount::getFixed(2),
403 ConstantInt::get(Type::getInt64Ty(C
), 0))},
406 GEPVec
->insertBefore(RI
);
408 // Break the address space of the source value
409 GEPVec
->getOperandUse(0).set(ConstantAggregateZero::get(V2P2Ty
));
412 raw_string_ostream
ErrorOS(Error
);
413 EXPECT_TRUE(verifyFunction(*F
, &ErrorOS
));
415 StringRef(Error
).starts_with("GEP address space doesn't match type"))
419 TEST(VerifierTest
, DetectTaggedGlobalInSection
) {
422 GlobalVariable
*GV
= new GlobalVariable(
423 Type::getInt64Ty(C
), false, GlobalValue::InternalLinkage
,
424 ConstantInt::get(Type::getInt64Ty(C
), 1));
425 GV
->setDSOLocal(true);
426 GlobalValue::SanitizerMetadata MD
{};
428 GV
->setSanitizerMetadata(MD
);
429 GV
->setSection("foo");
430 M
.insertGlobalVariable(GV
);
433 raw_string_ostream
ErrorOS(Error
);
434 EXPECT_TRUE(verifyModule(M
, &ErrorOS
));
436 StringRef(Error
).starts_with("tagged GlobalValue must not be in section"))
440 } // end anonymous namespace
441 } // end namespace llvm