diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 27 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 21 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 11 |
3 files changed, 53 insertions, 6 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 1b7d9bf6a3..765bc27df0 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -105,6 +105,7 @@ public: typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy; typedef llvm::SmallPtrSet<NodeTy*,2> RetsStackAddrTy; typedef llvm::SmallPtrSet<NodeTy*,2> RetsUndefTy; + typedef llvm::SmallPtrSet<NodeTy*,2> OutOfBoundMemAccessesTy; protected: @@ -170,6 +171,14 @@ protected: /// message expressions where a pass-by-value argument has an undefined /// value. UndefArgsTy MsgExprUndefArgs; + + /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from + /// out-of-bound memory accesses where the index MAY be out-of-bound. + OutOfBoundMemAccessesTy ImplicitOOBMemAccesses; + + /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from + /// out-of-bound memory accesses where the index MUST be out-of-bound. + OutOfBoundMemAccessesTy ExplicitOOBMemAccesses; public: GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L, @@ -282,7 +291,7 @@ public: bool isUndefArg(const NodeTy* N) const { return N->isSink() && (UndefArgs.find(const_cast<NodeTy*>(N)) != UndefArgs.end() || - MsgExprUndefArgs.find(const_cast<NodeTy*>(N)) != MsgExprUndefArgs.end()); + MsgExprUndefArgs.find(const_cast<NodeTy*>(N)) != MsgExprUndefArgs.end()); } bool isUndefReceiver(const NodeTy* N) const { @@ -362,7 +371,21 @@ public: undef_receivers_iterator undef_receivers_end() { return UndefReceivers.end(); } - + + typedef OutOfBoundMemAccessesTy::iterator oob_memacc_iterator; + oob_memacc_iterator implicit_oob_memacc_begin() { + return ImplicitOOBMemAccesses.begin(); + } + oob_memacc_iterator implicit_oob_memacc_end() { + return ImplicitOOBMemAccesses.end(); + } + oob_memacc_iterator explicit_oob_memacc_begin() { + return ExplicitOOBMemAccesses.begin(); + } + oob_memacc_iterator explicit_oob_memacc_end() { + return ExplicitOOBMemAccesses.end(); + } + void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C); /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 6de910fc17..084796cd99 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1088,7 +1088,20 @@ const GRState* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred, if (isFeasibleOutBound) { // Report warning. - StOutBound = 0; + // Make sink node manually. + ProgramPoint::Kind K = isLoad ? ProgramPoint::PostLoadKind + : ProgramPoint::PostStoreKind; + + NodeTy* OOBNode = Builder->generateNode(Ex, StOutBound, Pred, K); + + if (OOBNode) { + OOBNode->markAsSink(); + + if (isFeasibleInBound) + ImplicitOOBMemAccesses.insert(OOBNode); + else + ExplicitOOBMemAccesses.insert(OOBNode); + } } return isFeasibleInBound ? StInBound : NULL; @@ -2529,8 +2542,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, SVal LHSVal; - if (Result.isUnknown() && (Loc::IsLocType(CTy) || - (CTy->isScalarType() && CTy->isIntegerType()))) { + if (Result.isUnknown() && (Loc::IsLocType(CTy) + || (CTy->isScalarType() && CTy->isIntegerType()))) { unsigned Count = Builder->getCurrentBlockCount(); @@ -2542,7 +2555,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, ? cast<SVal>(loc::SymbolVal(Sym)) : cast<SVal>(nonloc::SymbolVal(Sym)); - // However, we need to convert the symbol to the computation type. + // However, we need to convert the symbol to the computation type. Result = (LTy == CTy) ? LHSVal : EvalCast(LHSVal,CTy); } else { diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index b4d4cb2c56..be7282314d 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -322,6 +322,16 @@ public: } }; +class VISIBILITY_HIDDEN OutOfBoundMemoryAccess : public BuiltinBug { +public: + OutOfBoundMemoryAccess() : BuiltinBug("out-of-bound memory access", + "Load or store into an out-of-bound memory position.") {} + + virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) { + Emit(BR, Eng.explicit_oob_memacc_begin(), Eng.explicit_oob_memacc_end()); + } +}; + //===----------------------------------------------------------------------===// // __attribute__(nonnull) checking @@ -392,5 +402,6 @@ void GRExprEngine::RegisterInternalChecks() { Register(new BadArg()); Register(new BadMsgExprArg()); Register(new BadReceiver()); + Register(new OutOfBoundMemoryAccess()); AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass); } |