85 static const unsigned Read = 1;
86 static const unsigned Write = 2;
87 static const unsigned Callee = 4;
88 static const unsigned Branchee = 8;
99 Type *Ty,
unsigned Flags);
124 Value *findValue(
Value *V,
bool OffsetOk)
const;
136 std::string Messages;
156 for (
const Value *V : Vs) {
159 if (isa<Instruction>(V)) {
160 MessagesStr << *V <<
'\n';
172 void CheckFailed(
const Twine &Message) { MessagesStr << Message <<
'\n'; }
178 template <
typename T1,
typename... Ts>
179 void CheckFailed(
const Twine &Message,
const T1 &V1,
const Ts &...Vs) {
180 CheckFailed(Message);
181 WriteValues({V1, Vs...});
197 #define Assert(C, ...) \ 198 do { if (!(C)) { CheckFailed(__VA_ARGS__); return; } } while (false) 206 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
207 AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
208 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
209 TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
211 dbgs() << MessagesStr.str();
220 "Unusual: Unnamed function with non-local linkage", &
F);
225 void Lint::visitCallSite(
CallSite CS) {
232 if (
Function *F = dyn_cast<Function>(findValue(Callee,
235 "Undefined behavior: Caller and callee calling convention differ",
239 unsigned NumActualArgs = CS.
arg_size();
241 Assert(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs
242 : FT->getNumParams() == NumActualArgs,
243 "Undefined behavior: Call argument count mismatches callee " 248 "Undefined behavior: Call return type mismatches " 249 "callee return type",
256 for (; AI != AE; ++AI) {
261 "Undefined behavior: Call argument type mismatches " 262 "callee parameter type",
276 if (AI != BI && (*BI)->getType()->isPointerTy()) {
279 "Unusual: noalias argument aliases another argument", &I);
287 cast<PointerType>(Formal->
getType())->getElementType();
288 visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty),
289 DL->getABITypeAlignment(Ty), Ty,
290 MemRef::Read | MemRef::Write);
307 Assert(!isa<AllocaInst>(Obj),
308 "Undefined behavior: Call with \"tail\" keyword references " 317 switch (II->getIntrinsicID()) {
335 dyn_cast<ConstantInt>(findValue(MCI->
getLength(),
337 if (Len->getValue().isIntN(32))
341 "Undefined behavior: memcpy source and destination overlap", &I);
363 "Undefined behavior: va_start called in a non-varargs function",
367 nullptr, MemRef::Read | MemRef::Write);
371 nullptr, MemRef::Write);
373 nullptr, MemRef::Read);
377 nullptr, MemRef::Read | MemRef::Write);
385 nullptr, MemRef::Read | MemRef::Write);
391 return visitCallSite(&I);
395 return visitCallSite(&I);
401 "Unusual: Return statement in function with noreturn attribute", &
I);
404 Value *Obj = findValue(V,
true);
405 Assert(!isa<AllocaInst>(Obj),
"Unusual: Returning alloca value", &I);
413 Type *Ty,
unsigned Flags) {
420 Assert(!isa<ConstantPointerNull>(UnderlyingObject),
421 "Undefined behavior: Null pointer dereference", &I);
422 Assert(!isa<UndefValue>(UnderlyingObject),
423 "Undefined behavior: Undef pointer dereference", &I);
424 Assert(!isa<ConstantInt>(UnderlyingObject) ||
425 !cast<ConstantInt>(UnderlyingObject)->isMinusOne(),
426 "Unusual: All-ones pointer dereference", &I);
427 Assert(!isa<ConstantInt>(UnderlyingObject) ||
428 !cast<ConstantInt>(UnderlyingObject)->isOne(),
429 "Unusual: Address one pointer dereference", &I);
431 if (Flags & MemRef::Write) {
432 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(UnderlyingObject))
433 Assert(!GV->isConstant(),
"Undefined behavior: Write to read-only memory",
435 Assert(!isa<Function>(UnderlyingObject) &&
436 !isa<BlockAddress>(UnderlyingObject),
437 "Undefined behavior: Write to text section", &I);
439 if (Flags & MemRef::Read) {
440 Assert(!isa<Function>(UnderlyingObject),
"Unusual: Load from function body",
442 Assert(!isa<BlockAddress>(UnderlyingObject),
443 "Undefined behavior: Load from block address", &I);
445 if (Flags & MemRef::Callee) {
446 Assert(!isa<BlockAddress>(UnderlyingObject),
447 "Undefined behavior: Call to block address", &I);
449 if (Flags & MemRef::Branchee) {
450 Assert(!isa<Constant>(UnderlyingObject) ||
451 isa<BlockAddress>(UnderlyingObject),
452 "Undefined behavior: Branch to non-blockaddress", &I);
464 unsigned BaseAlign = 0;
467 Type *ATy = AI->getAllocatedType();
468 if (!AI->isArrayAllocation() && ATy->
isSized())
469 BaseSize = DL->getTypeAllocSize(ATy);
470 BaseAlign = AI->getAlignment();
471 if (BaseAlign == 0 && ATy->
isSized())
472 BaseAlign = DL->getABITypeAlignment(ATy);
476 if (GV->hasDefinitiveInitializer()) {
477 Type *GTy = GV->getValueType();
479 BaseSize = DL->getTypeAllocSize(GTy);
480 BaseAlign = GV->getAlignment();
481 if (BaseAlign == 0 && GTy->
isSized())
482 BaseAlign = DL->getABITypeAlignment(GTy);
490 (Offset >= 0 && Offset +
Size <= BaseSize),
491 "Undefined behavior: Buffer overflow", &I);
495 if (Align == 0 && Ty && Ty->
isSized())
496 Align = DL->getABITypeAlignment(Ty);
498 "Undefined behavior: Memory reference address is misaligned", &I);
502 void Lint::visitLoadInst(
LoadInst &I) {
508 void Lint::visitStoreInst(
StoreInst &I) {
517 "Undefined result: xor(undef, undef)", &I);
522 "Undefined result: sub(undef, undef)", &I);
529 "Undefined result: Shift count out of range", &I);
534 dyn_cast<ConstantInt>(findValue(I.
getOperand(1),
false)))
536 "Undefined result: Shift count out of range", &I);
541 dyn_cast<ConstantInt>(findValue(I.
getOperand(1),
false)))
543 "Undefined result: Shift count out of range", &I);
549 if (isa<UndefValue>(V))
570 if (isa<UndefValue>(Elem))
583 "Undefined behavior: Division by zero", &I);
588 "Undefined behavior: Division by zero", &I);
593 "Undefined behavior: Division by zero", &I);
598 "Undefined behavior: Division by zero", &I);
605 "Pessimization: Static alloca outside of entry block", &
I);
610 void Lint::visitVAArgInst(
VAArgInst &I) {
612 nullptr, MemRef::Read | MemRef::Write);
617 nullptr, MemRef::Branchee);
620 "Undefined behavior: indirectbr with no destinations", &
I);
627 "Undefined result: extractelement index out of range", &I);
634 "Undefined result: insertelement index out of range", &I);
641 "Unusual: unreachable immediately preceded by instruction without " 653 Value *Lint::findValue(
Value *V,
bool OffsetOk)
const {
655 return findValueImpl(V, OffsetOk, Visited);
659 Value *Lint::findValueImpl(
Value *V,
bool OffsetOk,
662 if (!Visited.
insert(V).second)
671 if (
LoadInst *L = dyn_cast<LoadInst>(V)) {
676 if (!VisitedBlocks.
insert(BB).second)
680 return findValueImpl(U, OffsetOk, Visited);
681 if (BBI != BB->
begin())
break;
686 }
else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
687 if (
Value *
W = PN->hasConstantValue())
689 return findValueImpl(
W, OffsetOk, Visited);
690 }
else if (
CastInst *CI = dyn_cast<CastInst>(V)) {
691 if (CI->isNoopCast(*DL))
692 return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
697 return findValueImpl(
W, OffsetOk, Visited);
698 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
702 CE->getOperand(0)->getType(), CE->getType(),
704 return findValueImpl(CE->getOperand(0), OffsetOk, Visited);
705 }
else if (CE->getOpcode() == Instruction::ExtractValue) {
709 return findValueImpl(
W, OffsetOk, Visited);
714 if (
Instruction *Inst = dyn_cast<Instruction>(V)) {
716 return findValueImpl(
W, OffsetOk, Visited);
717 }
else if (
auto *
C = dyn_cast<Constant>(V)) {
720 return findValueImpl(
W, OffsetOk, Visited);
741 Lint *V =
new Lint();
750 Lint *V =
new Lint();
752 PM.
run(const_cast<Module&>(M));
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Return a value (possibly void), from a function.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, OptimizationRemarkEmitter *ORE=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
User::op_iterator arg_iterator
The type of iterator to use when looping over actual arguments at this call site. ...
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
void lintModule(const Module &M)
Check a module.
bool hasLocalLinkage() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents an incoming formal argument to a Function.
Base class for instruction visitors.
unsigned arg_size() const
CallingConv::ID getCallingConv() const
Get the calling convention of the call.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
static constexpr LocationSize unknown()
This class represents a function call, abstracting a target machine's calling convention.
cl::opt< unsigned > DefMaxInstsToScan
The default number of maximum instructions to scan in the block, used by FindAvailableLoadedValue().
void lintFunction(const Function &F)
lintFunction - Check a function for errors, printing messages on stderr.
An immutable pass that tracks lazily created AssumptionCache objects.
unsigned getSourceAlignment() const
iterator_range< IterTy > args() const
A cache of @llvm.assume calls within a function.
static LocationSize precise(uint64_t Value)
This class wraps the llvm.memset intrinsic.
block Block Frequency true
An instruction for reading from memory.
Value * getLength() const
unsigned getNumDestinations() const
return the number of possible destinations in this indirectbr instruction.
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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.
This class wraps the llvm.memmove intrinsic.
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, AliasAnalysis *AA=nullptr, bool *IsLoadCSE=nullptr, unsigned *NumScanedInst=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
InstrTy * getInstruction() const
unsigned getDestAlignment() const
uint64_t getNumElements() const
This file implements a class to represent arbitrary precision integral constant values and operations...
ValTy * getCalledValue() const
Return the pointer to function that is being called.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Attempt to fold the constant using the specified DataLayout.
A constant value that is initialized with an expression using other constant values.
Class to represent function types.
Type * getType() const
All values are typed, get the type of this value.
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
An instruction for storing to memory.
VectorType * getType() const
Overload to return most specific vector type.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
amdgpu Simplify well known AMD library false Value * Callee
Value * getOperand(unsigned i) const
bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
bool isCall() const
Return true if a CallInst is enclosed.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
AliasResult
The possible results of an alias query.
bool isZeroValue() const
Return true if the value is negative zero or null value.
PassManager manages ModulePassManagers.
const BasicBlock & getEntryBlock() const
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
static bool runOnFunction(Function &F, bool PostInlining)
This instruction inserts a single (scalar) element into a VectorType value.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static bool isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DstTy, const DataLayout &DL)
A no-op cast is one that can be effected without changing any bits.
This function has undefined behavior.
This is an important base class in LLVM.
bool hasStructRetAttr() const
Return true if this argument has the sret attribute.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isPointerTy() const
True if this is an instance of PointerType.
const Instruction & front() const
Indirect Branch Instruction.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool doesNotReturn() const
Determine if the function cannot return.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Value * getPointerOperand()
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
self_iterator getIterator()
bool isZero() const
Returns true if value is all zero.
FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
const Value * getArraySize() const
Get the number of elements allocated.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
INITIALIZE_PASS_BEGIN(Lint, "lint", "Statically lint-checks LLVM IR", false, true) INITIALIZE_PASS_END(Lint
Value * FindInsertedValue(Value *V, ArrayRef< unsigned > idx_range, Instruction *InsertBefore=nullptr)
Given an aggregrate and an sequence of indices, see if the scalar value indexed is already around as ...
FunctionPass * createLintPass()
Create a lint pass.
The two locations precisely alias each other.
Iterator for intrusive lists based on ilist_node.
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const
Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind).
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
ValTy * getArgument(unsigned ArgNo) const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
void initializeLintPass(PassRegistry &)
This class wraps the llvm.memcpy intrinsic.
AttributeList getAttributes() const
Return the parameter attributes for this call.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
The access may modify the value stored in memory.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Class to represent vector types.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
void setPreservesAll()
Set by analyses that do not transform their input at all.
amdgpu Simplify well known AMD library false Value Value * Arg
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
unsigned getAlignment() const
Return the alignment of the access that is being performed.
This file provides utility analysis objects describing memory locations.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
This class implements an extremely fast bulk output stream that can only output to a stream...
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it...
Legacy analysis pass which computes a DominatorTree.
AttributeList getAttributes() const
Get the parameter attributes of the call.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
The two locations alias, but only due to a partial overlap.
Value * SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, OptimizationRemarkEmitter *ORE=nullptr)
See if we can compute a simplified version of this instruction.
Value * getPointerOperand()
Statically lint checks LLVM IR
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack