X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FLint.cpp;h=f130f30c49daec77947e1d2b245769bab2723f44;hb=a704bc9354d8b03fd98da9bd7de5ae1dc49af961;hp=f7be3298522bbe933a30c6de7b50524cd0aaf877;hpb=2ab36d350293c77fc8941ce1023e4899df7e3a82;p=oota-llvm.git diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp index f7be3298522..f130f30c49d 100644 --- a/lib/Analysis/Lint.cpp +++ b/lib/Analysis/Lint.cpp @@ -70,7 +70,7 @@ namespace { void visitCallSite(CallSite CS); void visitMemoryReference(Instruction &I, Value *Ptr, - unsigned Size, unsigned Align, + uint64_t Size, unsigned Align, const Type *Ty, unsigned Flags); void visitCallInst(CallInst &I); @@ -108,7 +108,9 @@ namespace { raw_string_ostream MessagesStr; static char ID; // Pass identification, replacement for typeid - Lint() : FunctionPass(ID), MessagesStr(Messages) {} + Lint() : FunctionPass(ID), MessagesStr(Messages) { + initializeLintPass(*PassRegistry::getPassRegistry()); + } virtual bool runOnFunction(Function &F); @@ -191,7 +193,8 @@ void Lint::visitCallSite(CallSite CS) { Instruction &I = *CS.getInstruction(); Value *Callee = CS.getCalledValue(); - visitMemoryReference(I, Callee, ~0u, 0, 0, MemRef::Callee); + visitMemoryReference(I, Callee, AliasAnalysis::UnknownSize, + 0, 0, MemRef::Callee); if (Function *F = dyn_cast(findValue(Callee, /*OffsetOk=*/false))) { Assert1(CS.getCallingConv() == F->getCallingConv(), @@ -223,15 +226,17 @@ void Lint::visitCallSite(CallSite CS) { "Undefined behavior: Call argument type mismatches " "callee parameter type", &I); - // Check that noalias arguments don't alias other arguments. The - // AliasAnalysis API isn't expressive enough for what we really want - // to do. Known partial overlap is not distinguished from the case - // where nothing is known. + // Check that noalias arguments don't alias other arguments. This is + // not fully precise because we don't know the sizes of the dereferenced + // memory regions. if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy()) - for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI) { - Assert1(AI == BI || AA->alias(*AI, *BI) != AliasAnalysis::MustAlias, - "Unusual: noalias argument aliases another argument", &I); - } + for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI) + if (AI != BI && (*BI)->getType()->isPointerTy()) { + AliasAnalysis::AliasResult Result = AA->alias(*AI, *BI); + Assert1(Result != AliasAnalysis::MustAlias && + Result != AliasAnalysis::PartialAlias, + "Unusual: noalias argument aliases another argument", &I); + } // Check that an sret argument points to valid memory. if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) { @@ -264,15 +269,17 @@ void Lint::visitCallSite(CallSite CS) { case Intrinsic::memcpy: { MemCpyInst *MCI = cast(&I); // TODO: If the size is known, use it. - visitMemoryReference(I, MCI->getDest(), ~0u, MCI->getAlignment(), 0, + visitMemoryReference(I, MCI->getDest(), AliasAnalysis::UnknownSize, + MCI->getAlignment(), 0, MemRef::Write); - visitMemoryReference(I, MCI->getSource(), ~0u, MCI->getAlignment(), 0, + visitMemoryReference(I, MCI->getSource(), AliasAnalysis::UnknownSize, + MCI->getAlignment(), 0, MemRef::Read); // Check that the memcpy arguments don't overlap. The AliasAnalysis API // isn't expressive enough for what we really want to do. Known partial // overlap is not distinguished from the case where nothing is known. - unsigned Size = 0; + uint64_t Size = 0; if (const ConstantInt *Len = dyn_cast(findValue(MCI->getLength(), /*OffsetOk=*/false))) @@ -286,16 +293,19 @@ void Lint::visitCallSite(CallSite CS) { case Intrinsic::memmove: { MemMoveInst *MMI = cast(&I); // TODO: If the size is known, use it. - visitMemoryReference(I, MMI->getDest(), ~0u, MMI->getAlignment(), 0, + visitMemoryReference(I, MMI->getDest(), AliasAnalysis::UnknownSize, + MMI->getAlignment(), 0, MemRef::Write); - visitMemoryReference(I, MMI->getSource(), ~0u, MMI->getAlignment(), 0, + visitMemoryReference(I, MMI->getSource(), AliasAnalysis::UnknownSize, + MMI->getAlignment(), 0, MemRef::Read); break; } case Intrinsic::memset: { MemSetInst *MSI = cast(&I); // TODO: If the size is known, use it. - visitMemoryReference(I, MSI->getDest(), ~0u, MSI->getAlignment(), 0, + visitMemoryReference(I, MSI->getDest(), AliasAnalysis::UnknownSize, + MSI->getAlignment(), 0, MemRef::Write); break; } @@ -305,24 +315,26 @@ void Lint::visitCallSite(CallSite CS) { "Undefined behavior: va_start called in a non-varargs function", &I); - visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, - MemRef::Read | MemRef::Write); + visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize, + 0, 0, MemRef::Read | MemRef::Write); break; case Intrinsic::vacopy: - visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, MemRef::Write); - visitMemoryReference(I, CS.getArgument(1), ~0u, 0, 0, MemRef::Read); + visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize, + 0, 0, MemRef::Write); + visitMemoryReference(I, CS.getArgument(1), AliasAnalysis::UnknownSize, + 0, 0, MemRef::Read); break; case Intrinsic::vaend: - visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, - MemRef::Read | MemRef::Write); + visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize, + 0, 0, MemRef::Read | MemRef::Write); break; case Intrinsic::stackrestore: // Stackrestore doesn't read or write memory, but it sets the // stack pointer, which the compiler may read from or write to // at any time, so check it for both readability and writeability. - visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, - MemRef::Read | MemRef::Write); + visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize, + 0, 0, MemRef::Read | MemRef::Write); break; } } @@ -351,7 +363,7 @@ void Lint::visitReturnInst(ReturnInst &I) { // TODO: Check that the reference is in bounds. // TODO: Check readnone/readonly function attributes. void Lint::visitMemoryReference(Instruction &I, - Value *Ptr, unsigned Size, unsigned Align, + Value *Ptr, uint64_t Size, unsigned Align, const Type *Ty, unsigned Flags) { // If no memory is being referenced, it doesn't matter if the pointer // is valid. @@ -495,12 +507,13 @@ void Lint::visitAllocaInst(AllocaInst &I) { } void Lint::visitVAArgInst(VAArgInst &I) { - visitMemoryReference(I, I.getOperand(0), ~0u, 0, 0, + visitMemoryReference(I, I.getOperand(0), AliasAnalysis::UnknownSize, 0, 0, MemRef::Read | MemRef::Write); } void Lint::visitIndirectBrInst(IndirectBrInst &I) { - visitMemoryReference(I, I.getAddress(), ~0u, 0, 0, MemRef::Branchee); + visitMemoryReference(I, I.getAddress(), AliasAnalysis::UnknownSize, 0, 0, + MemRef::Branchee); Assert1(I.getNumDestinations() != 0, "Undefined behavior: indirectbr with no destinations", &I); @@ -554,7 +567,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, // TODO: Look through eliminable cast pairs. // TODO: Look through calls with unique return values. // TODO: Look through vector insert/extract/shuffle. - V = OffsetOk ? V->getUnderlyingObject() : V->stripPointerCasts(); + V = OffsetOk ? GetUnderlyingObject(V, TD) : V->stripPointerCasts(); if (LoadInst *L = dyn_cast(V)) { BasicBlock::iterator BBI = L; BasicBlock *BB = L->getParent(); @@ -570,8 +583,9 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, BBI = BB->end(); } } else if (PHINode *PN = dyn_cast(V)) { - if (Value *W = PN->hasConstantValue(DT)) - return findValueImpl(W, OffsetOk, Visited); + if (Value *W = PN->hasConstantValue()) + if (W != V) + return findValueImpl(W, OffsetOk, Visited); } else if (CastInst *CI = dyn_cast(V)) { if (CI->isNoopCast(TD ? TD->getIntPtrType(V->getContext()) : Type::getInt64Ty(V->getContext()))) @@ -592,7 +606,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, Type::getInt64Ty(V->getContext()))) return findValueImpl(CE->getOperand(0), OffsetOk, Visited); } else if (CE->getOpcode() == Instruction::ExtractValue) { - const SmallVector &Indices = CE->getIndices(); + ArrayRef Indices = CE->getIndices(); if (Value *W = FindInsertedValue(CE->getOperand(0), Indices.begin(), Indices.end())) @@ -603,9 +617,8 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, // As a last resort, try SimplifyInstruction or constant folding. if (Instruction *Inst = dyn_cast(V)) { - if (Value *W = SimplifyInstruction(Inst, TD)) - if (W != Inst) - return findValueImpl(W, OffsetOk, Visited); + if (Value *W = SimplifyInstruction(Inst, TD, DT)) + return findValueImpl(W, OffsetOk, Visited); } else if (ConstantExpr *CE = dyn_cast(V)) { if (Value *W = ConstantFoldConstantExpression(CE, TD)) if (W != V)