forked from OSchip/llvm-project
[Lint][Verifier] NFC: Rename 'Assert*' macros to 'Check*'.
The LLVM IR verifier and analysis linter defines and uses several macros in code that performs validation of IR expectations. Previously, these macros were named with an 'Assert' prefix. These names were misleading since the macro definitions are not conditioned on build kind; they are defined identically in builds that have asserts enabled and those that do not. This was confusing since an LLVM developer might expect these macros to be conditionally enabled as 'assert' is. Further confusion was possible since the LLVM IR verifier is implicitly disabled (in Clang::ConstructJob()) for builds without asserts enabled, but only for Clang driver invocations; not for clang -cc1 invocations. This could make it appear that the macros were not active for builds without asserts enabled, e.g. when investigating behavior using the Clang driver, and thus lead to surprises when running tests that exercise the clang -cc1 interface. This change renames this set of macros as follows: Assert -> Check AssertDI -> CheckDI AssertTBAA -> CheckTBAA
This commit is contained in:
parent
019e7b7f6e
commit
c54ad13602
|
@ -166,8 +166,8 @@ public:
|
|||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
// Assert - We know that cond should be true, if not print an error message.
|
||||
#define Assert(C, ...) \
|
||||
// Check - We know that cond should be true, if not print an error message.
|
||||
#define Check(C, ...) \
|
||||
do { \
|
||||
if (!(C)) { \
|
||||
CheckFailed(__VA_ARGS__); \
|
||||
|
@ -178,8 +178,8 @@ public:
|
|||
void Lint::visitFunction(Function &F) {
|
||||
// This isn't undefined behavior, it's just a little unusual, and it's a
|
||||
// fairly common mistake to neglect to name a function.
|
||||
Assert(F.hasName() || F.hasLocalLinkage(),
|
||||
"Unusual: Unnamed function with non-local linkage", &F);
|
||||
Check(F.hasName() || F.hasLocalLinkage(),
|
||||
"Unusual: Unnamed function with non-local linkage", &F);
|
||||
|
||||
// TODO: Check for irreducible control flow.
|
||||
}
|
||||
|
@ -192,23 +192,23 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
|
||||
if (Function *F = dyn_cast<Function>(findValue(Callee,
|
||||
/*OffsetOk=*/false))) {
|
||||
Assert(I.getCallingConv() == F->getCallingConv(),
|
||||
"Undefined behavior: Caller and callee calling convention differ",
|
||||
&I);
|
||||
Check(I.getCallingConv() == F->getCallingConv(),
|
||||
"Undefined behavior: Caller and callee calling convention differ",
|
||||
&I);
|
||||
|
||||
FunctionType *FT = F->getFunctionType();
|
||||
unsigned NumActualArgs = I.arg_size();
|
||||
|
||||
Assert(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs
|
||||
: FT->getNumParams() == NumActualArgs,
|
||||
"Undefined behavior: Call argument count mismatches callee "
|
||||
"argument count",
|
||||
&I);
|
||||
Check(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs
|
||||
: FT->getNumParams() == NumActualArgs,
|
||||
"Undefined behavior: Call argument count mismatches callee "
|
||||
"argument count",
|
||||
&I);
|
||||
|
||||
Assert(FT->getReturnType() == I.getType(),
|
||||
"Undefined behavior: Call return type mismatches "
|
||||
"callee return type",
|
||||
&I);
|
||||
Check(FT->getReturnType() == I.getType(),
|
||||
"Undefined behavior: Call return type mismatches "
|
||||
"callee return type",
|
||||
&I);
|
||||
|
||||
// Check argument types (in case the callee was casted) and attributes.
|
||||
// TODO: Verify that caller and callee attributes are compatible.
|
||||
|
@ -218,10 +218,10 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
Value *Actual = *AI;
|
||||
if (PI != PE) {
|
||||
Argument *Formal = &*PI++;
|
||||
Assert(Formal->getType() == Actual->getType(),
|
||||
"Undefined behavior: Call argument type mismatches "
|
||||
"callee parameter type",
|
||||
&I);
|
||||
Check(Formal->getType() == Actual->getType(),
|
||||
"Undefined behavior: Call argument type mismatches "
|
||||
"callee parameter type",
|
||||
&I);
|
||||
|
||||
// Check that noalias arguments don't alias other arguments. This is
|
||||
// not fully precise because we don't know the sizes of the dereferenced
|
||||
|
@ -239,9 +239,9 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
continue;
|
||||
if (AI != BI && (*BI)->getType()->isPointerTy()) {
|
||||
AliasResult Result = AA->alias(*AI, *BI);
|
||||
Assert(Result != AliasResult::MustAlias &&
|
||||
Result != AliasResult::PartialAlias,
|
||||
"Unusual: noalias argument aliases another argument", &I);
|
||||
Check(Result != AliasResult::MustAlias &&
|
||||
Result != AliasResult::PartialAlias,
|
||||
"Unusual: noalias argument aliases another argument", &I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,10 +268,10 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
if (PAL.hasParamAttr(ArgNo++, Attribute::ByVal))
|
||||
continue;
|
||||
Value *Obj = findValue(Arg, /*OffsetOk=*/true);
|
||||
Assert(!isa<AllocaInst>(Obj),
|
||||
"Undefined behavior: Call with \"tail\" keyword references "
|
||||
"alloca",
|
||||
&I);
|
||||
Check(!isa<AllocaInst>(Obj),
|
||||
"Undefined behavior: Call with \"tail\" keyword references "
|
||||
"alloca",
|
||||
&I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,9 +299,9 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
/*OffsetOk=*/false)))
|
||||
if (Len->getValue().isIntN(32))
|
||||
Size = LocationSize::precise(Len->getValue().getZExtValue());
|
||||
Assert(AA->alias(MCI->getSource(), Size, MCI->getDest(), Size) !=
|
||||
AliasResult::MustAlias,
|
||||
"Undefined behavior: memcpy source and destination overlap", &I);
|
||||
Check(AA->alias(MCI->getSource(), Size, MCI->getDest(), Size) !=
|
||||
AliasResult::MustAlias,
|
||||
"Undefined behavior: memcpy source and destination overlap", &I);
|
||||
break;
|
||||
}
|
||||
case Intrinsic::memcpy_inline: {
|
||||
|
@ -316,9 +316,9 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
// isn't expressive enough for what we really want to do. Known partial
|
||||
// overlap is not distinguished from the case where nothing is known.
|
||||
const LocationSize LS = LocationSize::precise(Size);
|
||||
Assert(AA->alias(MCII->getSource(), LS, MCII->getDest(), LS) !=
|
||||
AliasResult::MustAlias,
|
||||
"Undefined behavior: memcpy source and destination overlap", &I);
|
||||
Check(AA->alias(MCII->getSource(), LS, MCII->getDest(), LS) !=
|
||||
AliasResult::MustAlias,
|
||||
"Undefined behavior: memcpy source and destination overlap", &I);
|
||||
break;
|
||||
}
|
||||
case Intrinsic::memmove: {
|
||||
|
@ -337,9 +337,9 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
}
|
||||
|
||||
case Intrinsic::vastart:
|
||||
Assert(I.getParent()->getParent()->isVarArg(),
|
||||
"Undefined behavior: va_start called in a non-varargs function",
|
||||
&I);
|
||||
Check(I.getParent()->getParent()->isVarArg(),
|
||||
"Undefined behavior: va_start called in a non-varargs function",
|
||||
&I);
|
||||
|
||||
visitMemoryReference(I, MemoryLocation::getForArgument(&I, 0, TLI), None,
|
||||
nullptr, MemRef::Read | MemRef::Write);
|
||||
|
@ -364,20 +364,22 @@ void Lint::visitCallBase(CallBase &I) {
|
|||
break;
|
||||
case Intrinsic::get_active_lane_mask:
|
||||
if (auto *TripCount = dyn_cast<ConstantInt>(I.getArgOperand(1)))
|
||||
Assert(!TripCount->isZero(), "get_active_lane_mask: operand #2 "
|
||||
"must be greater than 0", &I);
|
||||
Check(!TripCount->isZero(),
|
||||
"get_active_lane_mask: operand #2 "
|
||||
"must be greater than 0",
|
||||
&I);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Lint::visitReturnInst(ReturnInst &I) {
|
||||
Function *F = I.getParent()->getParent();
|
||||
Assert(!F->doesNotReturn(),
|
||||
"Unusual: Return statement in function with noreturn attribute", &I);
|
||||
Check(!F->doesNotReturn(),
|
||||
"Unusual: Return statement in function with noreturn attribute", &I);
|
||||
|
||||
if (Value *V = I.getReturnValue()) {
|
||||
Value *Obj = findValue(V, /*OffsetOk=*/true);
|
||||
Assert(!isa<AllocaInst>(Obj), "Unusual: Returning alloca value", &I);
|
||||
Check(!isa<AllocaInst>(Obj), "Unusual: Returning alloca value", &I);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,39 +394,39 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
|
|||
|
||||
Value *Ptr = const_cast<Value *>(Loc.Ptr);
|
||||
Value *UnderlyingObject = findValue(Ptr, /*OffsetOk=*/true);
|
||||
Assert(!isa<ConstantPointerNull>(UnderlyingObject),
|
||||
"Undefined behavior: Null pointer dereference", &I);
|
||||
Assert(!isa<UndefValue>(UnderlyingObject),
|
||||
"Undefined behavior: Undef pointer dereference", &I);
|
||||
Assert(!isa<ConstantInt>(UnderlyingObject) ||
|
||||
!cast<ConstantInt>(UnderlyingObject)->isMinusOne(),
|
||||
"Unusual: All-ones pointer dereference", &I);
|
||||
Assert(!isa<ConstantInt>(UnderlyingObject) ||
|
||||
!cast<ConstantInt>(UnderlyingObject)->isOne(),
|
||||
"Unusual: Address one pointer dereference", &I);
|
||||
Check(!isa<ConstantPointerNull>(UnderlyingObject),
|
||||
"Undefined behavior: Null pointer dereference", &I);
|
||||
Check(!isa<UndefValue>(UnderlyingObject),
|
||||
"Undefined behavior: Undef pointer dereference", &I);
|
||||
Check(!isa<ConstantInt>(UnderlyingObject) ||
|
||||
!cast<ConstantInt>(UnderlyingObject)->isMinusOne(),
|
||||
"Unusual: All-ones pointer dereference", &I);
|
||||
Check(!isa<ConstantInt>(UnderlyingObject) ||
|
||||
!cast<ConstantInt>(UnderlyingObject)->isOne(),
|
||||
"Unusual: Address one pointer dereference", &I);
|
||||
|
||||
if (Flags & MemRef::Write) {
|
||||
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject))
|
||||
Assert(!GV->isConstant(), "Undefined behavior: Write to read-only memory",
|
||||
&I);
|
||||
Assert(!isa<Function>(UnderlyingObject) &&
|
||||
!isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Write to text section", &I);
|
||||
Check(!GV->isConstant(), "Undefined behavior: Write to read-only memory",
|
||||
&I);
|
||||
Check(!isa<Function>(UnderlyingObject) &&
|
||||
!isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Write to text section", &I);
|
||||
}
|
||||
if (Flags & MemRef::Read) {
|
||||
Assert(!isa<Function>(UnderlyingObject), "Unusual: Load from function body",
|
||||
&I);
|
||||
Assert(!isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Load from block address", &I);
|
||||
Check(!isa<Function>(UnderlyingObject), "Unusual: Load from function body",
|
||||
&I);
|
||||
Check(!isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Load from block address", &I);
|
||||
}
|
||||
if (Flags & MemRef::Callee) {
|
||||
Assert(!isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Call to block address", &I);
|
||||
Check(!isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Call to block address", &I);
|
||||
}
|
||||
if (Flags & MemRef::Branchee) {
|
||||
Assert(!isa<Constant>(UnderlyingObject) ||
|
||||
isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Branch to non-blockaddress", &I);
|
||||
Check(!isa<Constant>(UnderlyingObject) ||
|
||||
isa<BlockAddress>(UnderlyingObject),
|
||||
"Undefined behavior: Branch to non-blockaddress", &I);
|
||||
}
|
||||
|
||||
// Check for buffer overflows and misalignment.
|
||||
|
@ -458,17 +460,17 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc,
|
|||
|
||||
// Accesses from before the start or after the end of the object are not
|
||||
// defined.
|
||||
Assert(!Loc.Size.hasValue() || BaseSize == MemoryLocation::UnknownSize ||
|
||||
(Offset >= 0 && Offset + Loc.Size.getValue() <= BaseSize),
|
||||
"Undefined behavior: Buffer overflow", &I);
|
||||
Check(!Loc.Size.hasValue() || BaseSize == MemoryLocation::UnknownSize ||
|
||||
(Offset >= 0 && Offset + Loc.Size.getValue() <= BaseSize),
|
||||
"Undefined behavior: Buffer overflow", &I);
|
||||
|
||||
// Accesses that say that the memory is more aligned than it is are not
|
||||
// defined.
|
||||
if (!Align && Ty && Ty->isSized())
|
||||
Align = DL->getABITypeAlign(Ty);
|
||||
if (BaseAlign && Align)
|
||||
Assert(*Align <= commonAlignment(*BaseAlign, Offset),
|
||||
"Undefined behavior: Memory reference address is misaligned", &I);
|
||||
Check(*Align <= commonAlignment(*BaseAlign, Offset),
|
||||
"Undefined behavior: Memory reference address is misaligned", &I);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,34 +485,34 @@ void Lint::visitStoreInst(StoreInst &I) {
|
|||
}
|
||||
|
||||
void Lint::visitXor(BinaryOperator &I) {
|
||||
Assert(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
|
||||
"Undefined result: xor(undef, undef)", &I);
|
||||
Check(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
|
||||
"Undefined result: xor(undef, undef)", &I);
|
||||
}
|
||||
|
||||
void Lint::visitSub(BinaryOperator &I) {
|
||||
Assert(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
|
||||
"Undefined result: sub(undef, undef)", &I);
|
||||
Check(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)),
|
||||
"Undefined result: sub(undef, undef)", &I);
|
||||
}
|
||||
|
||||
void Lint::visitLShr(BinaryOperator &I) {
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(1),
|
||||
/*OffsetOk=*/false)))
|
||||
Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
Check(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
}
|
||||
|
||||
void Lint::visitAShr(BinaryOperator &I) {
|
||||
if (ConstantInt *CI =
|
||||
dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false)))
|
||||
Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
Check(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
}
|
||||
|
||||
void Lint::visitShl(BinaryOperator &I) {
|
||||
if (ConstantInt *CI =
|
||||
dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false)))
|
||||
Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
Check(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()),
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
}
|
||||
|
||||
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
|
||||
|
@ -551,30 +553,30 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
|
|||
}
|
||||
|
||||
void Lint::visitSDiv(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
Check(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitUDiv(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
Check(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitSRem(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
Check(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitURem(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
Check(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitAllocaInst(AllocaInst &I) {
|
||||
if (isa<ConstantInt>(I.getArraySize()))
|
||||
// This isn't undefined behavior, it's just an obvious pessimization.
|
||||
Assert(&I.getParent()->getParent()->getEntryBlock() == I.getParent(),
|
||||
"Pessimization: Static alloca outside of entry block", &I);
|
||||
Check(&I.getParent()->getParent()->getEntryBlock() == I.getParent(),
|
||||
"Pessimization: Static alloca outside of entry block", &I);
|
||||
|
||||
// TODO: Check for an unusual size (MSB set?)
|
||||
}
|
||||
|
@ -588,14 +590,14 @@ void Lint::visitIndirectBrInst(IndirectBrInst &I) {
|
|||
visitMemoryReference(I, MemoryLocation::getAfter(I.getAddress()), None,
|
||||
nullptr, MemRef::Branchee);
|
||||
|
||||
Assert(I.getNumDestinations() != 0,
|
||||
"Undefined behavior: indirectbr with no destinations", &I);
|
||||
Check(I.getNumDestinations() != 0,
|
||||
"Undefined behavior: indirectbr with no destinations", &I);
|
||||
}
|
||||
|
||||
void Lint::visitExtractElementInst(ExtractElementInst &I) {
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getIndexOperand(),
|
||||
/*OffsetOk=*/false)))
|
||||
Assert(
|
||||
Check(
|
||||
CI->getValue().ult(
|
||||
cast<FixedVectorType>(I.getVectorOperandType())->getNumElements()),
|
||||
"Undefined result: extractelement index out of range", &I);
|
||||
|
@ -604,18 +606,18 @@ void Lint::visitExtractElementInst(ExtractElementInst &I) {
|
|||
void Lint::visitInsertElementInst(InsertElementInst &I) {
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(2),
|
||||
/*OffsetOk=*/false)))
|
||||
Assert(CI->getValue().ult(
|
||||
cast<FixedVectorType>(I.getType())->getNumElements()),
|
||||
"Undefined result: insertelement index out of range", &I);
|
||||
Check(CI->getValue().ult(
|
||||
cast<FixedVectorType>(I.getType())->getNumElements()),
|
||||
"Undefined result: insertelement index out of range", &I);
|
||||
}
|
||||
|
||||
void Lint::visitUnreachableInst(UnreachableInst &I) {
|
||||
// This isn't undefined behavior, it's merely suspicious.
|
||||
Assert(&I == &I.getParent()->front() ||
|
||||
std::prev(I.getIterator())->mayHaveSideEffects(),
|
||||
"Unusual: unreachable immediately preceded by instruction without "
|
||||
"side effects",
|
||||
&I);
|
||||
Check(&I == &I.getParent()->front() ||
|
||||
std::prev(I.getIterator())->mayHaveSideEffects(),
|
||||
"Unusual: unreachable immediately preceded by instruction without "
|
||||
"side effects",
|
||||
&I);
|
||||
}
|
||||
|
||||
/// findValue - Look through bitcasts and simple memory reference patterns
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue