62 static const unsigned Read = 1;
63 static const unsigned Write = 2;
64 static const unsigned Callee = 4;
65 static const unsigned Branchee = 8;
75 uint64_t Size,
unsigned Align,
112 std::string Messages;
120 bool runOnFunction(
Function &
F)
override;
132 for (
const Value *V : Vs) {
135 if (isa<Instruction>(V)) {
136 MessagesStr << *V <<
'\n';
138 V->printAsOperand(MessagesStr,
true, Mod);
148 void CheckFailed(
const Twine &Message) { MessagesStr << Message <<
'\n'; }
154 template <
typename T1,
typename... Ts>
155 void CheckFailed(
const Twine &Message,
const T1 &V1,
const Ts &...Vs) {
156 CheckFailed(Message);
157 WriteValues({V1, Vs...});
173 #define Assert(C, ...) \
174 do { if (!(C)) { CheckFailed(__VA_ARGS__); return; } } while (0)
181 AA = &getAnalysis<AliasAnalysis>();
182 AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
183 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
184 TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
186 dbgs() << MessagesStr.str();
195 "Unusual: Unnamed function with non-local linkage", &
F);
200 void Lint::visitCallSite(
CallSite CS) {
203 const DataLayout &
DL = CS->getModule()->getDataLayout();
208 if (
Function *F = dyn_cast<Function>(findValue(Callee, DL,
211 "Undefined behavior: Caller and callee calling convention differ",
215 unsigned NumActualArgs = CS.
arg_size();
217 Assert(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs
218 : FT->getNumParams() == NumActualArgs,
219 "Undefined behavior: Call argument count mismatches callee "
224 "Undefined behavior: Call return type mismatches "
225 "callee return type",
232 for (; AI != AE; ++AI) {
237 "Undefined behavior: Call argument type mismatches "
238 "callee parameter type",
246 if (AI != BI && (*BI)->getType()->isPointerTy()) {
249 "Unusual: noalias argument aliases another argument", &I);
255 cast<PointerType>(Formal->
getType())->getElementType();
256 visitMemoryReference(I, Actual, AA->getTypeStoreSize(Ty),
258 MemRef::Read | MemRef::Write);
267 Value *Obj = findValue(*AI, DL,
true);
268 Assert(!isa<AllocaInst>(Obj),
269 "Undefined behavior: Call with \"tail\" keyword references "
276 switch (II->getIntrinsicID()) {
281 case Intrinsic::memcpy: {
294 dyn_cast<ConstantInt>(findValue(MCI->
getLength(), DL,
296 if (Len->getValue().isIntN(32))
297 Size = Len->getValue().getZExtValue();
300 "Undefined behavior: memcpy source and destination overlap", &I);
303 case Intrinsic::memmove: {
312 case Intrinsic::memset: {
320 case Intrinsic::vastart:
322 "Undefined behavior: va_start called in a non-varargs function",
326 nullptr, MemRef::Read | MemRef::Write);
328 case Intrinsic::vacopy:
330 nullptr, MemRef::Write);
332 nullptr, MemRef::Read);
334 case Intrinsic::vaend:
336 nullptr, MemRef::Read | MemRef::Write);
339 case Intrinsic::stackrestore:
344 nullptr, MemRef::Read | MemRef::Write);
347 case Intrinsic::eh_begincatch:
348 visitEHBeginCatch(II);
350 case Intrinsic::eh_endcatch:
356 void Lint::visitCallInst(
CallInst &I) {
357 return visitCallSite(&I);
361 return visitCallSite(&I);
367 "Unusual: Return statement in function with noreturn attribute", &
I);
372 Assert(!isa<AllocaInst>(Obj),
"Unusual: Returning alloca value", &I);
386 Value *UnderlyingObject =
388 Assert(!isa<ConstantPointerNull>(UnderlyingObject),
389 "Undefined behavior: Null pointer dereference", &I);
390 Assert(!isa<UndefValue>(UnderlyingObject),
391 "Undefined behavior: Undef pointer dereference", &I);
392 Assert(!isa<ConstantInt>(UnderlyingObject) ||
393 !cast<ConstantInt>(UnderlyingObject)->isAllOnesValue(),
394 "Unusual: All-ones pointer dereference", &I);
395 Assert(!isa<ConstantInt>(UnderlyingObject) ||
396 !cast<ConstantInt>(UnderlyingObject)->isOne(),
397 "Unusual: Address one pointer dereference", &I);
399 if (Flags & MemRef::Write) {
400 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject))
401 Assert(!GV->isConstant(),
"Undefined behavior: Write to read-only memory",
403 Assert(!isa<Function>(UnderlyingObject) &&
404 !isa<BlockAddress>(UnderlyingObject),
405 "Undefined behavior: Write to text section", &I);
407 if (Flags & MemRef::Read) {
408 Assert(!isa<Function>(UnderlyingObject),
"Unusual: Load from function body",
410 Assert(!isa<BlockAddress>(UnderlyingObject),
411 "Undefined behavior: Load from block address", &I);
413 if (Flags & MemRef::Callee) {
414 Assert(!isa<BlockAddress>(UnderlyingObject),
415 "Undefined behavior: Call to block address", &I);
417 if (Flags & MemRef::Branchee) {
418 Assert(!isa<Constant>(UnderlyingObject) ||
419 isa<BlockAddress>(UnderlyingObject),
420 "Undefined behavior: Branch to non-blockaddress", &I);
433 unsigned BaseAlign = 0;
435 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
436 Type *ATy = AI->getAllocatedType();
437 if (!AI->isArrayAllocation() && ATy->
isSized())
439 BaseAlign = AI->getAlignment();
440 if (BaseAlign == 0 && ATy->
isSized())
445 if (GV->hasDefinitiveInitializer()) {
446 Type *GTy = GV->getType()->getElementType();
449 BaseAlign = GV->getAlignment();
450 if (BaseAlign == 0 && GTy->
isSized())
459 (Offset >= 0 && Offset + Size <= BaseSize),
460 "Undefined behavior: Buffer overflow", &I);
464 if (Align == 0 && Ty && Ty->
isSized())
467 "Undefined behavior: Memory reference address is misaligned", &I);
471 void Lint::visitLoadInst(
LoadInst &I) {
477 void Lint::visitStoreInst(
StoreInst &I) {
486 "Undefined result: xor(undef, undef)", &I);
491 "Undefined result: sub(undef, undef)", &I);
499 "Undefined result: Shift count out of range", &I);
503 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
506 "Undefined result: Shift count out of range", &I);
510 if (
ConstantInt *CI = dyn_cast<ConstantInt>(findValue(
513 "Undefined result: Shift count out of range", &I);
526 if (VisitedBlocks.
count(Pred))
546 *SecondBeginCatch = IC;
557 if (VisitedBlocks.
count(Succ))
596 "llvm.eh.begincatch may be reachable without passing a landingpad",
600 VisitedBlocks.
clear();
607 CatchBB, std::next(static_cast<BasicBlock::iterator>(II)),
608 &SecondBeginCatch, VisitedBlocks);
610 SecondBeginCatch ==
nullptr,
611 "llvm.eh.begincatch may be called a second time before llvm.eh.endcatch",
612 II, SecondBeginCatch);
614 "Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch",
631 *SecondEndCatch = IC;
635 if (isa<LandingPadInst>(*RI))
644 if (VisitedBlocks.
count(Pred))
685 bool BeginCatchFound =
687 &SecondEndCatch, VisitedBlocks);
689 SecondEndCatch ==
nullptr,
690 "llvm.eh.endcatch may be called a second time after llvm.eh.begincatch",
693 "llvm.eh.endcatch may be reachable without passing llvm.eh.begincatch",
700 if (isa<UndefValue>(V))
706 APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
708 dyn_cast<Instruction>(V), DT);
709 return KnownZero.isAllOnesValue();
725 if (isa<UndefValue>(Elem))
728 APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
730 if (KnownZero.isAllOnesValue())
739 "Undefined behavior: Division by zero", &I);
744 "Undefined behavior: Division by zero", &I);
749 "Undefined behavior: Division by zero", &I);
754 "Undefined behavior: Division by zero", &I);
761 "Pessimization: Static alloca outside of entry block", &
I);
766 void Lint::visitVAArgInst(
VAArgInst &I) {
768 nullptr, MemRef::Read | MemRef::Write);
773 nullptr, MemRef::Branchee);
776 "Undefined behavior: indirectbr with no destinations", &
I);
784 "Undefined result: extractelement index out of range", &I);
792 "Undefined result: insertelement index out of range", &I);
799 "Unusual: unreachable immediately preceded by instruction without "
813 return findValueImpl(V, DL, OffsetOk, Visited);
820 if (!Visited.
insert(V).second)
829 if (
LoadInst *L = dyn_cast<LoadInst>(V)) {
834 if (!VisitedBlocks.
insert(BB).second)
838 return findValueImpl(U, DL, OffsetOk, Visited);
839 if (BBI != BB->
begin())
break;
844 }
else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
845 if (
Value *W = PN->hasConstantValue())
847 return findValueImpl(W, DL, OffsetOk, Visited);
848 }
else if (
CastInst *CI = dyn_cast<CastInst>(V)) {
849 if (CI->isNoopCast(DL))
850 return findValueImpl(CI->getOperand(0), DL, OffsetOk, Visited);
855 return findValueImpl(W, DL, OffsetOk, Visited);
856 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
860 CE->getOperand(0)->getType(),
CE->getType(),
862 return findValueImpl(
CE->getOperand(0), DL, OffsetOk, Visited);
863 }
else if (
CE->getOpcode() == Instruction::ExtractValue) {
867 return findValueImpl(W, DL, OffsetOk, Visited);
872 if (
Instruction *Inst = dyn_cast<Instruction>(V)) {
874 return findValueImpl(W, DL, OffsetOk, Visited);
875 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
878 return findValueImpl(W, DL, OffsetOk, Visited);
896 assert(!F.
isDeclaration() &&
"Cannot lint external functions");
899 Lint *V =
new Lint();
908 Lint *V =
new Lint();
910 PM.
run(const_cast<Module&>(M));
unsigned getAlignment() const
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type (if unknown returns 0).
bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute on it in its containing function.
The two locations precisely alias each other.
ReturnInst - Return a value (possibly void), from a function.
A parsed version of the target data layout string in and methods for querying it. ...
void lintModule(const Module &M)
Check a module.
BasicBlock * getUniquePredecessor()
Return the predecessor of this block if it has a unique predecessor block.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM Argument representation.
Base class for instruction visitors.
ValTy * getArgument(unsigned ArgNo) const
A Module instance is used to store all the information related to an LLVM module. ...
InstrTy * getInstruction() const
Intrinsic::ID getIntrinsicID() const
getIntrinsicID - Return the intrinsic ID of this intrinsic.
The two locations alias, but only due to a partial overlap.
CallInst - This class represents a function call, abstracting a target machine's calling convention...
void lintFunction(const Function &F)
lintFunction - Check a function for errors, printing messages on stderr.
Statically lint checks LLVM false
An immutable pass that tracks lazily created AssumptionCache objects.
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
A cache of .assume calls within a function.
MemSetInst - This class wraps the llvm.memset intrinsic.
const Function * getParent() const
Return the enclosing method, or null if none.
LoadInst - an instruction for reading from memory.
INITIALIZE_PASS_BEGIN(Lint,"lint","Statically lint-checks LLVM IR", false, true) INITIALIZE_PASS_END(Lint
User::op_iterator arg_iterator
arg_iterator - The type of iterator to use when looping over actual arguments at this call site...
Constant * ConstantFoldConstantExpression(const ConstantExpr *CE, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstantExpression - Attempt to fold the constant expression using the specified DataLayo...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
void add(Pass *P) override
Add a pass to the queue of passes to run.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This is the base class for all instructions that perform data casts.
MemMoveInst - This class wraps the llvm.memmove intrinsic.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
static bool isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DstTy, Type *IntPtrTy)
A no-op cast is one that can be effected without changing any bits.
bool isSized(SmallPtrSetImpl< const Type * > *Visited=nullptr) const
isSized - Return true if it makes sense to take the size of this type.
Windows NT (Windows on ARM)
static bool allSuccessorsReachEndCatch(BasicBlock *BB, BasicBlock::iterator InstBegin, IntrinsicInst **SecondBeginCatch, SmallSet< BasicBlock *, 4 > &VisitedBlocks)
ConstantExpr - a constant value that is initialized with an expression using other constant values...
FunctionType - Class to represent function types.
VectorType * getType() const
getType - Overload to return most specific vector type.
ValTy * getCalledValue() const
getCalledValue - Return the pointer to function that is being called.
bool hasStructRetAttr() const
Return true if this argument has the sret attribute on it in its containing function.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if it can be expressed as a b...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
StoreInst - an instruction for storing to memory.
unsigned getNumElements() const
Return the number of elements in the Vector type.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Type * getElementType() const
PassManager manages ModulePassManagers.
InstListType::reverse_iterator reverse_iterator
InsertElementInst - This instruction inserts a single (scalar) element into a VectorType value...
unsigned getAlignment() const
getAlignment - Return the alignment of the access that is being performed
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
UnreachableInst - This function has undefined behavior.
This is an important base class in LLVM.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
IndirectBrInst - Indirect Branch Instruction.
bool succ_empty(const BasicBlock *BB)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static bool allPredCameFromBeginCatch(BasicBlock *BB, BasicBlock::reverse_iterator InstRbegin, IntrinsicInst **SecondEndCatch, SmallSet< BasicBlock *, 4 > &VisitedBlocks)
bool isZeroValue() const
Return true if the value is negative zero or null value.
bool doesNotReturn() const
Determine if the function cannot return.
AliasResult
The possible results of an alias query.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Value * getPointerOperand()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool pred_empty(const BasicBlock *BB)
Constant * getAggregateElement(unsigned Elt) const
getAggregateElement - For aggregates (struct/array/vector) return the constant that corresponds to th...
#define INITIALIZE_AG_DEPENDENCY(depName)
FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
bool isPointerTy() const
isPointerTy - True if this is an instance of PointerType.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
VAArgInst - This class represents the va_arg llvm instruction, which returns an argument of the speci...
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
GetUnderlyingObject - This method strips off any GEP address adjustments and pointer casts from the s...
Value * FindInsertedValue(Value *V, ArrayRef< unsigned > idx_range, Instruction *InsertBefore=nullptr)
FindInsertedValue - Given an aggregrate and an sequence of indices, see if the scalar value indexed i...
FunctionPass * createLintPass()
Create a lint pass.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
static bool allPredsCameFromLandingPad(BasicBlock *BB, SmallSet< BasicBlock *, 4 > &VisitedBlocks)
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
unsigned getIntegerBitWidth() const
This is the shared class of boolean and integer constants.
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Value * getDest() const
getDest - This is just like getRawDest, but it strips off any cast instructions that feed it...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
Value * getLength() const
unsigned arg_size() const
void initializeLintPass(PassRegistry &)
MemCpyInst - This class wraps the llvm.memcpy intrinsic.
pred_range predecessors(BasicBlock *BB)
const BasicBlock & getEntryBlock() const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
VectorType - Class to represent vector types.
Class for arbitrary precision integers.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Value * getSource() const
getSource - This is just like getRawSource, but it strips off any cast instructions that feed it...
uint64_t MinAlign(uint64_t A, uint64_t B)
MinAlign - A and B are either alignments or offsets.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
unsigned getAlignment() const
getAlignment - Return the alignment of the access that is being performed
CallingConv::ID getCallingConv() const
getCallingConv/setCallingConv - get or set the calling convention of the call.
bool isLandingPad() const
Return true if this basic block is a landing pad.
FunctionType * getFunctionType() const
bool hasLocalLinkage() const
Value * FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=6, AliasAnalysis *AA=nullptr, AAMDNodes *AATags=nullptr)
FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the instruction before ScanFr...
A raw_ostream that writes to an std::string.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
succ_range successors(BasicBlock *BB)
const Value * getArraySize() const
getArraySize - Get the number of elements allocated.
This class implements an extremely fast bulk output stream that can only output to a stream...
InvokeInst - Invoke instruction.
IterTy arg_begin() const
arg_begin/arg_end - Return iterators corresponding to the actual argument list for a call site...
C - The default llvm calling convention, compatible with C.
Value * SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr)
SimplifyInstruction - See if we can compute a simplified version of this instruction.
Legacy analysis pass which computes a DominatorTree.
bool isCall() const
isCall - true if a CallInst is enclosed.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Value * getPointerOperand()
unsigned getNumDestinations() const
getNumDestinations - return the number of possible destinations in this indirectbr instruction...
Statically lint checks LLVM IR
const BasicBlock * getParent() const
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.
AllocaInst - an instruction to allocate memory on the stack.