@@ -166,8 +166,8 @@ class Lint : public InstVisitor<Lint> {
166
166
};
167
167
} // end anonymous namespace
168
168
169
- // Assert - We know that cond should be true, if not print an error message.
170
- #define Assert (C, ...) \
169
+ // Check - We know that cond should be true, if not print an error message.
170
+ #define Check (C, ...) \
171
171
do { \
172
172
if (!(C)) { \
173
173
CheckFailed (__VA_ARGS__); \
@@ -178,8 +178,8 @@ class Lint : public InstVisitor<Lint> {
178
178
void Lint::visitFunction (Function &F) {
179
179
// This isn't undefined behavior, it's just a little unusual, and it's a
180
180
// fairly common mistake to neglect to name a function.
181
- Assert (F.hasName () || F.hasLocalLinkage (),
182
- " Unusual: Unnamed function with non-local linkage" , &F);
181
+ Check (F.hasName () || F.hasLocalLinkage (),
182
+ " Unusual: Unnamed function with non-local linkage" , &F);
183
183
184
184
// TODO: Check for irreducible control flow.
185
185
}
@@ -192,23 +192,23 @@ void Lint::visitCallBase(CallBase &I) {
192
192
193
193
if (Function *F = dyn_cast<Function>(findValue (Callee,
194
194
/* OffsetOk=*/ false ))) {
195
- Assert (I.getCallingConv () == F->getCallingConv (),
196
- " Undefined behavior: Caller and callee calling convention differ" ,
197
- &I);
195
+ Check (I.getCallingConv () == F->getCallingConv (),
196
+ " Undefined behavior: Caller and callee calling convention differ" ,
197
+ &I);
198
198
199
199
FunctionType *FT = F->getFunctionType ();
200
200
unsigned NumActualArgs = I.arg_size ();
201
201
202
- Assert (FT->isVarArg () ? FT->getNumParams () <= NumActualArgs
203
- : FT->getNumParams () == NumActualArgs,
204
- " Undefined behavior: Call argument count mismatches callee "
205
- " argument count" ,
206
- &I);
202
+ Check (FT->isVarArg () ? FT->getNumParams () <= NumActualArgs
203
+ : FT->getNumParams () == NumActualArgs,
204
+ " Undefined behavior: Call argument count mismatches callee "
205
+ " argument count" ,
206
+ &I);
207
207
208
- Assert (FT->getReturnType () == I.getType (),
209
- " Undefined behavior: Call return type mismatches "
210
- " callee return type" ,
211
- &I);
208
+ Check (FT->getReturnType () == I.getType (),
209
+ " Undefined behavior: Call return type mismatches "
210
+ " callee return type" ,
211
+ &I);
212
212
213
213
// Check argument types (in case the callee was casted) and attributes.
214
214
// TODO: Verify that caller and callee attributes are compatible.
@@ -218,10 +218,10 @@ void Lint::visitCallBase(CallBase &I) {
218
218
Value *Actual = *AI;
219
219
if (PI != PE) {
220
220
Argument *Formal = &*PI++;
221
- Assert (Formal->getType () == Actual->getType (),
222
- " Undefined behavior: Call argument type mismatches "
223
- " callee parameter type" ,
224
- &I);
221
+ Check (Formal->getType () == Actual->getType (),
222
+ " Undefined behavior: Call argument type mismatches "
223
+ " callee parameter type" ,
224
+ &I);
225
225
226
226
// Check that noalias arguments don't alias other arguments. This is
227
227
// not fully precise because we don't know the sizes of the dereferenced
@@ -239,9 +239,9 @@ void Lint::visitCallBase(CallBase &I) {
239
239
continue ;
240
240
if (AI != BI && (*BI)->getType ()->isPointerTy ()) {
241
241
AliasResult Result = AA->alias (*AI, *BI);
242
- Assert (Result != AliasResult::MustAlias &&
243
- Result != AliasResult::PartialAlias,
244
- " Unusual: noalias argument aliases another argument" , &I);
242
+ Check (Result != AliasResult::MustAlias &&
243
+ Result != AliasResult::PartialAlias,
244
+ " Unusual: noalias argument aliases another argument" , &I);
245
245
}
246
246
}
247
247
}
@@ -268,10 +268,10 @@ void Lint::visitCallBase(CallBase &I) {
268
268
if (PAL.hasParamAttr (ArgNo++, Attribute::ByVal))
269
269
continue ;
270
270
Value *Obj = findValue (Arg, /* OffsetOk=*/ true );
271
- Assert (!isa<AllocaInst>(Obj),
272
- " Undefined behavior: Call with \" tail\" keyword references "
273
- " alloca" ,
274
- &I);
271
+ Check (!isa<AllocaInst>(Obj),
272
+ " Undefined behavior: Call with \" tail\" keyword references "
273
+ " alloca" ,
274
+ &I);
275
275
}
276
276
}
277
277
}
@@ -299,9 +299,9 @@ void Lint::visitCallBase(CallBase &I) {
299
299
/* OffsetOk=*/ false )))
300
300
if (Len->getValue ().isIntN (32 ))
301
301
Size = LocationSize::precise (Len->getValue ().getZExtValue ());
302
- Assert (AA->alias (MCI->getSource (), Size, MCI->getDest (), Size) !=
303
- AliasResult::MustAlias,
304
- " Undefined behavior: memcpy source and destination overlap" , &I);
302
+ Check (AA->alias (MCI->getSource (), Size, MCI->getDest (), Size) !=
303
+ AliasResult::MustAlias,
304
+ " Undefined behavior: memcpy source and destination overlap" , &I);
305
305
break ;
306
306
}
307
307
case Intrinsic::memcpy_inline: {
@@ -316,9 +316,9 @@ void Lint::visitCallBase(CallBase &I) {
316
316
// isn't expressive enough for what we really want to do. Known partial
317
317
// overlap is not distinguished from the case where nothing is known.
318
318
const LocationSize LS = LocationSize::precise (Size);
319
- Assert (AA->alias (MCII->getSource (), LS, MCII->getDest (), LS) !=
320
- AliasResult::MustAlias,
321
- " Undefined behavior: memcpy source and destination overlap" , &I);
319
+ Check (AA->alias (MCII->getSource (), LS, MCII->getDest (), LS) !=
320
+ AliasResult::MustAlias,
321
+ " Undefined behavior: memcpy source and destination overlap" , &I);
322
322
break ;
323
323
}
324
324
case Intrinsic::memmove: {
@@ -337,9 +337,9 @@ void Lint::visitCallBase(CallBase &I) {
337
337
}
338
338
339
339
case Intrinsic::vastart:
340
- Assert (I.getParent ()->getParent ()->isVarArg (),
341
- " Undefined behavior: va_start called in a non-varargs function" ,
342
- &I);
340
+ Check (I.getParent ()->getParent ()->isVarArg (),
341
+ " Undefined behavior: va_start called in a non-varargs function" ,
342
+ &I);
343
343
344
344
visitMemoryReference (I, MemoryLocation::getForArgument (&I, 0 , TLI), None,
345
345
nullptr , MemRef::Read | MemRef::Write);
@@ -364,20 +364,22 @@ void Lint::visitCallBase(CallBase &I) {
364
364
break ;
365
365
case Intrinsic::get_active_lane_mask:
366
366
if (auto *TripCount = dyn_cast<ConstantInt>(I.getArgOperand (1 )))
367
- Assert (!TripCount->isZero (), " get_active_lane_mask: operand #2 "
368
- " must be greater than 0" , &I);
367
+ Check (!TripCount->isZero (),
368
+ " get_active_lane_mask: operand #2 "
369
+ " must be greater than 0" ,
370
+ &I);
369
371
break ;
370
372
}
371
373
}
372
374
373
375
void Lint::visitReturnInst (ReturnInst &I) {
374
376
Function *F = I.getParent ()->getParent ();
375
- Assert (!F->doesNotReturn (),
376
- " Unusual: Return statement in function with noreturn attribute" , &I);
377
+ Check (!F->doesNotReturn (),
378
+ " Unusual: Return statement in function with noreturn attribute" , &I);
377
379
378
380
if (Value *V = I.getReturnValue ()) {
379
381
Value *Obj = findValue (V, /* OffsetOk=*/ true );
380
- Assert (!isa<AllocaInst>(Obj), " Unusual: Returning alloca value" , &I);
382
+ Check (!isa<AllocaInst>(Obj), " Unusual: Returning alloca value" , &I);
381
383
}
382
384
}
383
385
@@ -392,39 +394,39 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
392
394
393
395
Value *Ptr = const_cast <Value *>(Loc.Ptr );
394
396
Value *UnderlyingObject = findValue (Ptr, /* OffsetOk=*/ true );
395
- Assert (!isa<ConstantPointerNull>(UnderlyingObject),
396
- " Undefined behavior: Null pointer dereference" , &I);
397
- Assert (!isa<UndefValue>(UnderlyingObject),
398
- " Undefined behavior: Undef pointer dereference" , &I);
399
- Assert (!isa<ConstantInt>(UnderlyingObject) ||
400
- !cast<ConstantInt>(UnderlyingObject)->isMinusOne (),
401
- " Unusual: All-ones pointer dereference" , &I);
402
- Assert (!isa<ConstantInt>(UnderlyingObject) ||
403
- !cast<ConstantInt>(UnderlyingObject)->isOne (),
404
- " Unusual: Address one pointer dereference" , &I);
397
+ Check (!isa<ConstantPointerNull>(UnderlyingObject),
398
+ " Undefined behavior: Null pointer dereference" , &I);
399
+ Check (!isa<UndefValue>(UnderlyingObject),
400
+ " Undefined behavior: Undef pointer dereference" , &I);
401
+ Check (!isa<ConstantInt>(UnderlyingObject) ||
402
+ !cast<ConstantInt>(UnderlyingObject)->isMinusOne (),
403
+ " Unusual: All-ones pointer dereference" , &I);
404
+ Check (!isa<ConstantInt>(UnderlyingObject) ||
405
+ !cast<ConstantInt>(UnderlyingObject)->isOne (),
406
+ " Unusual: Address one pointer dereference" , &I);
405
407
406
408
if (Flags & MemRef::Write) {
407
409
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject))
408
- Assert (!GV->isConstant (), " Undefined behavior: Write to read-only memory" ,
409
- &I);
410
- Assert (!isa<Function>(UnderlyingObject) &&
411
- !isa<BlockAddress>(UnderlyingObject),
412
- " Undefined behavior: Write to text section" , &I);
410
+ Check (!GV->isConstant (), " Undefined behavior: Write to read-only memory" ,
411
+ &I);
412
+ Check (!isa<Function>(UnderlyingObject) &&
413
+ !isa<BlockAddress>(UnderlyingObject),
414
+ " Undefined behavior: Write to text section" , &I);
413
415
}
414
416
if (Flags & MemRef::Read) {
415
- Assert (!isa<Function>(UnderlyingObject), " Unusual: Load from function body" ,
416
- &I);
417
- Assert (!isa<BlockAddress>(UnderlyingObject),
418
- " Undefined behavior: Load from block address" , &I);
417
+ Check (!isa<Function>(UnderlyingObject), " Unusual: Load from function body" ,
418
+ &I);
419
+ Check (!isa<BlockAddress>(UnderlyingObject),
420
+ " Undefined behavior: Load from block address" , &I);
419
421
}
420
422
if (Flags & MemRef::Callee) {
421
- Assert (!isa<BlockAddress>(UnderlyingObject),
422
- " Undefined behavior: Call to block address" , &I);
423
+ Check (!isa<BlockAddress>(UnderlyingObject),
424
+ " Undefined behavior: Call to block address" , &I);
423
425
}
424
426
if (Flags & MemRef::Branchee) {
425
- Assert (!isa<Constant>(UnderlyingObject) ||
426
- isa<BlockAddress>(UnderlyingObject),
427
- " Undefined behavior: Branch to non-blockaddress" , &I);
427
+ Check (!isa<Constant>(UnderlyingObject) ||
428
+ isa<BlockAddress>(UnderlyingObject),
429
+ " Undefined behavior: Branch to non-blockaddress" , &I);
428
430
}
429
431
430
432
// Check for buffer overflows and misalignment.
@@ -458,17 +460,17 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
458
460
459
461
// Accesses from before the start or after the end of the object are not
460
462
// defined.
461
- Assert (!Loc.Size .hasValue () || BaseSize == MemoryLocation::UnknownSize ||
462
- (Offset >= 0 && Offset + Loc.Size .getValue () <= BaseSize),
463
- " Undefined behavior: Buffer overflow" , &I);
463
+ Check (!Loc.Size .hasValue () || BaseSize == MemoryLocation::UnknownSize ||
464
+ (Offset >= 0 && Offset + Loc.Size .getValue () <= BaseSize),
465
+ " Undefined behavior: Buffer overflow" , &I);
464
466
465
467
// Accesses that say that the memory is more aligned than it is are not
466
468
// defined.
467
469
if (!Align && Ty && Ty->isSized ())
468
470
Align = DL->getABITypeAlign (Ty);
469
471
if (BaseAlign && Align)
470
- Assert (*Align <= commonAlignment (*BaseAlign, Offset),
471
- " Undefined behavior: Memory reference address is misaligned" , &I);
472
+ Check (*Align <= commonAlignment (*BaseAlign, Offset),
473
+ " Undefined behavior: Memory reference address is misaligned" , &I);
472
474
}
473
475
}
474
476
@@ -483,34 +485,34 @@ void Lint::visitStoreInst(StoreInst &I) {
483
485
}
484
486
485
487
void Lint::visitXor (BinaryOperator &I) {
486
- Assert (!isa<UndefValue>(I.getOperand (0 )) || !isa<UndefValue>(I.getOperand (1 )),
487
- " Undefined result: xor(undef, undef)" , &I);
488
+ Check (!isa<UndefValue>(I.getOperand (0 )) || !isa<UndefValue>(I.getOperand (1 )),
489
+ " Undefined result: xor(undef, undef)" , &I);
488
490
}
489
491
490
492
void Lint::visitSub (BinaryOperator &I) {
491
- Assert (!isa<UndefValue>(I.getOperand (0 )) || !isa<UndefValue>(I.getOperand (1 )),
492
- " Undefined result: sub(undef, undef)" , &I);
493
+ Check (!isa<UndefValue>(I.getOperand (0 )) || !isa<UndefValue>(I.getOperand (1 )),
494
+ " Undefined result: sub(undef, undef)" , &I);
493
495
}
494
496
495
497
void Lint::visitLShr (BinaryOperator &I) {
496
498
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue (I.getOperand (1 ),
497
499
/* OffsetOk=*/ false )))
498
- Assert (CI->getValue ().ult (cast<IntegerType>(I.getType ())->getBitWidth ()),
499
- " Undefined result: Shift count out of range" , &I);
500
+ Check (CI->getValue ().ult (cast<IntegerType>(I.getType ())->getBitWidth ()),
501
+ " Undefined result: Shift count out of range" , &I);
500
502
}
501
503
502
504
void Lint::visitAShr (BinaryOperator &I) {
503
505
if (ConstantInt *CI =
504
506
dyn_cast<ConstantInt>(findValue (I.getOperand (1 ), /* OffsetOk=*/ false )))
505
- Assert (CI->getValue ().ult (cast<IntegerType>(I.getType ())->getBitWidth ()),
506
- " Undefined result: Shift count out of range" , &I);
507
+ Check (CI->getValue ().ult (cast<IntegerType>(I.getType ())->getBitWidth ()),
508
+ " Undefined result: Shift count out of range" , &I);
507
509
}
508
510
509
511
void Lint::visitShl (BinaryOperator &I) {
510
512
if (ConstantInt *CI =
511
513
dyn_cast<ConstantInt>(findValue (I.getOperand (1 ), /* OffsetOk=*/ false )))
512
- Assert (CI->getValue ().ult (cast<IntegerType>(I.getType ())->getBitWidth ()),
513
- " Undefined result: Shift count out of range" , &I);
514
+ Check (CI->getValue ().ult (cast<IntegerType>(I.getType ())->getBitWidth ()),
515
+ " Undefined result: Shift count out of range" , &I);
514
516
}
515
517
516
518
static bool isZero (Value *V, const DataLayout &DL, DominatorTree *DT,
@@ -551,30 +553,30 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
551
553
}
552
554
553
555
void Lint::visitSDiv (BinaryOperator &I) {
554
- Assert (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
555
- " Undefined behavior: Division by zero" , &I);
556
+ Check (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
557
+ " Undefined behavior: Division by zero" , &I);
556
558
}
557
559
558
560
void Lint::visitUDiv (BinaryOperator &I) {
559
- Assert (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
560
- " Undefined behavior: Division by zero" , &I);
561
+ Check (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
562
+ " Undefined behavior: Division by zero" , &I);
561
563
}
562
564
563
565
void Lint::visitSRem (BinaryOperator &I) {
564
- Assert (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
565
- " Undefined behavior: Division by zero" , &I);
566
+ Check (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
567
+ " Undefined behavior: Division by zero" , &I);
566
568
}
567
569
568
570
void Lint::visitURem (BinaryOperator &I) {
569
- Assert (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
570
- " Undefined behavior: Division by zero" , &I);
571
+ Check (!isZero (I.getOperand (1 ), I.getModule ()->getDataLayout (), DT, AC),
572
+ " Undefined behavior: Division by zero" , &I);
571
573
}
572
574
573
575
void Lint::visitAllocaInst (AllocaInst &I) {
574
576
if (isa<ConstantInt>(I.getArraySize ()))
575
577
// This isn't undefined behavior, it's just an obvious pessimization.
576
- Assert (&I.getParent ()->getParent ()->getEntryBlock () == I.getParent (),
577
- " Pessimization: Static alloca outside of entry block" , &I);
578
+ Check (&I.getParent ()->getParent ()->getEntryBlock () == I.getParent (),
579
+ " Pessimization: Static alloca outside of entry block" , &I);
578
580
579
581
// TODO: Check for an unusual size (MSB set?)
580
582
}
@@ -588,14 +590,14 @@ void Lint::visitIndirectBrInst(IndirectBrInst &I) {
588
590
visitMemoryReference (I, MemoryLocation::getAfter (I.getAddress ()), None,
589
591
nullptr , MemRef::Branchee);
590
592
591
- Assert (I.getNumDestinations () != 0 ,
592
- " Undefined behavior: indirectbr with no destinations" , &I);
593
+ Check (I.getNumDestinations () != 0 ,
594
+ " Undefined behavior: indirectbr with no destinations" , &I);
593
595
}
594
596
595
597
void Lint::visitExtractElementInst (ExtractElementInst &I) {
596
598
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue (I.getIndexOperand (),
597
599
/* OffsetOk=*/ false )))
598
- Assert (
600
+ Check (
599
601
CI->getValue ().ult (
600
602
cast<FixedVectorType>(I.getVectorOperandType ())->getNumElements ()),
601
603
" Undefined result: extractelement index out of range" , &I);
@@ -604,18 +606,18 @@ void Lint::visitExtractElementInst(ExtractElementInst &I) {
604
606
void Lint::visitInsertElementInst (InsertElementInst &I) {
605
607
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue (I.getOperand (2 ),
606
608
/* OffsetOk=*/ false )))
607
- Assert (CI->getValue ().ult (
608
- cast<FixedVectorType>(I.getType ())->getNumElements ()),
609
- " Undefined result: insertelement index out of range" , &I);
609
+ Check (CI->getValue ().ult (
610
+ cast<FixedVectorType>(I.getType ())->getNumElements ()),
611
+ " Undefined result: insertelement index out of range" , &I);
610
612
}
611
613
612
614
void Lint::visitUnreachableInst (UnreachableInst &I) {
613
615
// This isn't undefined behavior, it's merely suspicious.
614
- Assert (&I == &I.getParent ()->front () ||
615
- std::prev (I.getIterator ())->mayHaveSideEffects (),
616
- " Unusual: unreachable immediately preceded by instruction without "
617
- " side effects" ,
618
- &I);
616
+ Check (&I == &I.getParent ()->front () ||
617
+ std::prev (I.getIterator ())->mayHaveSideEffects (),
618
+ " Unusual: unreachable immediately preceded by instruction without "
619
+ " side effects" ,
620
+ &I);
619
621
}
620
622
621
623
// / findValue - Look through bitcasts and simple memory reference patterns
0 commit comments