From: Zhongxing Xu Date: Sun, 23 Nov 2008 05:52:28 +0000 (+0000) Subject: Add out-of-bound memory access warning report code. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c0c23325312df5d40fe788ffcb48484f190e9a3;p=clang Add out-of-bound memory access warning report code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59903 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 UndefResultsTy; typedef llvm::SmallPtrSet RetsStackAddrTy; typedef llvm::SmallPtrSet RetsUndefTy; + typedef llvm::SmallPtrSet 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(N)) != UndefArgs.end() || - MsgExprUndefArgs.find(const_cast(N)) != MsgExprUndefArgs.end()); + MsgExprUndefArgs.find(const_cast(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(loc::SymbolVal(Sym)) : cast(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); }