diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp index 19945179f4d..db0a22fc381 100644 --- a/lib/Analysis/Lint.cpp +++ b/lib/Analysis/Lint.cpp @@ -63,6 +63,9 @@ namespace { void visitReturnInst(ReturnInst &I); void visitLoadInst(LoadInst &I); void visitStoreInst(StoreInst &I); + void visitLShr(BinaryOperator &I); + void visitAShr(BinaryOperator &I); + void visitShl(BinaryOperator &I); void visitSDiv(BinaryOperator &I); void visitUDiv(BinaryOperator &I); void visitSRem(BinaryOperator &I); @@ -70,6 +73,8 @@ namespace { void visitAllocaInst(AllocaInst &I); void visitVAArgInst(VAArgInst &I); void visitIndirectBrInst(IndirectBrInst &I); + void visitExtractElementInst(ExtractElementInst &I); + void visitInsertElementInst(InsertElementInst &I); public: Module *Mod; @@ -295,6 +300,27 @@ void Lint::visitStoreInst(StoreInst &I) { I.getOperand(0)->getType()); } +void Lint::visitLShr(BinaryOperator &I) { + if (ConstantInt *CI = + dyn_cast(I.getOperand(1)->stripPointerCasts())) + Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()), + "Shift count out of range", &I); +} + +void Lint::visitAShr(BinaryOperator &I) { + if (ConstantInt *CI = + dyn_cast(I.getOperand(1)->stripPointerCasts())) + Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()), + "Shift count out of range", &I); +} + +void Lint::visitShl(BinaryOperator &I) { + if (ConstantInt *CI = + dyn_cast(I.getOperand(1)->stripPointerCasts())) + Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()), + "Shift count out of range", &I); +} + static bool isZero(Value *V, TargetData *TD) { unsigned BitWidth = cast(V->getType())->getBitWidth(); APInt Mask = APInt::getAllOnesValue(BitWidth), @@ -334,6 +360,20 @@ void Lint::visitIndirectBrInst(IndirectBrInst &I) { visitMemoryReference(I, I.getAddress(), 0, 0); } +void Lint::visitExtractElementInst(ExtractElementInst &I) { + if (ConstantInt *CI = + dyn_cast(I.getIndexOperand()->stripPointerCasts())) + Assert1(CI->getValue().ult(I.getVectorOperandType()->getNumElements()), + "extractelement index out of range", &I); +} + +void Lint::visitInsertElementInst(InsertElementInst &I) { + if (ConstantInt *CI = + dyn_cast(I.getOperand(2)->stripPointerCasts())) + Assert1(CI->getValue().ult(I.getType()->getNumElements()), + "insertelement index out of range", &I); +} + //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// diff --git a/test/Other/lint.ll b/test/Other/lint.ll index 6ccaa6fd4c4..fb34c287b37 100644 --- a/test/Other/lint.ll +++ b/test/Other/lint.ll @@ -10,6 +10,10 @@ define i32 @foo() noreturn { store i32 0, i32* null ; CHECK: Null pointer dereference %t = load i32* null +; CHECK: Undef pointer dereference + store i32 0, i32* undef +; CHECK: Undef pointer dereference + %u = load i32* undef ; CHECK: Memory reference address is misaligned %x = inttoptr i32 1 to i32* load i32* %x, align 4 @@ -21,6 +25,16 @@ define i32 @foo() noreturn { %sr = srem i32 2, 0 ; CHECK: Division by zero %ur = urem i32 2, 0 +; CHECK: extractelement index out of range + %ee = extractelement <4 x i32> zeroinitializer, i32 4 +; CHECK: insertelement index out of range + %ie = insertelement <4 x i32> zeroinitializer, i32 0, i32 4 +; CHECK: Shift count out of range + %r = lshr i32 0, 32 +; CHECK: Shift count out of range + %q = ashr i32 0, 32 +; CHECK: Shift count out of range + %l = shl i32 0, 32 br label %next next: