diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-25 02:10:28 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-25 02:10:28 +0000 |
commit | 945a246ad8eb82a1ec3d01a6bdae624afab94aa9 (patch) | |
tree | 7bae59d56977492d157622ed84f4ec478c382ee2 | |
parent | 7d564c3b4a901d92b7ab781aec74dd5dbab87a3d (diff) | |
download | bcm5719-llvm-945a246ad8eb82a1ec3d01a6bdae624afab94aa9.tar.gz bcm5719-llvm-945a246ad8eb82a1ec3d01a6bdae624afab94aa9.zip |
Added logic to check for uninitialized values as the receivers for message expressions
and uninitialized values passed-by-value as arguments to message expressions.
llvm-svn: 48760
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/GRExprEngine.h | 10 | ||||
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 72 |
2 files changed, 74 insertions, 8 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index b15d3baf566..c96324f4cd1 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -72,6 +72,7 @@ protected: typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy; typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy; typedef llvm::SmallPtrSet<NodeTy*,2> BadCallsTy; + typedef llvm::SmallPtrSet<NodeTy*,2> UndefReceiversTy; typedef llvm::DenseMap<NodeTy*, Expr*> UndefArgsTy; typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy; typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy; @@ -120,10 +121,19 @@ protected: /// pointers that are NULL (or other constants) or Undefined. BadCallsTy BadCalls; + /// UndefReceiver - Nodes in the ExplodedGraph resulting from message + /// ObjC message expressions where the receiver is undefined (uninitialized). + UndefReceiversTy UndefReceivers; + /// UndefArg - Nodes in the ExplodedGraph resulting from calls to functions /// where a pass-by-value argument has an undefined value. UndefArgsTy UndefArgs; + /// MsgExprUndefArgs - Nodes in the ExplodedGraph resulting from + /// message expressions where a pass-by-value argument has an undefined + /// value. + UndefArgsTy MsgExprUndefArgs; + public: GRExprEngine(GraphTy& g) : G(g), Liveness(G.getCFG()), diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index c143bd5dd3c..55bfe551199 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -1088,10 +1088,10 @@ void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred, } void GRExprEngine::VisitObjCMessageExprHelper(ObjCMessageExpr* ME, - ObjCMessageExpr::arg_iterator I, - ObjCMessageExpr::arg_iterator E, + ObjCMessageExpr::arg_iterator AI, + ObjCMessageExpr::arg_iterator AE, NodeTy* Pred, NodeSet& Dst) { - if (I == E) { + if (AI == AE) { // Process the receiver. @@ -1101,19 +1101,75 @@ void GRExprEngine::VisitObjCMessageExprHelper(ObjCMessageExpr* ME, // FIXME: More logic for the processing the method call. - for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) - Dst.Add(*NI); + for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) { + + ValueState* St = GetState(*NI); + RVal L = GetLVal(St, Receiver); + + // Check for undefined control-flow or calls to NULL. + + if (L.isUndef()) { + NodeTy* N = Builder->generateNode(ME, St, *NI); + + if (N) { + N->markAsSink(); + UndefReceivers.insert(N); + } + + continue; + } + + // Check for any arguments that are uninitialized/undefined. + + bool badArg = false; + + for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end(); + I != E; ++I) { + + if (GetRVal(St, *I).isUndef()) { + + NodeTy* N = Builder->generateNode(ME, St, *NI); + + if (N) { + N->markAsSink(); + MsgExprUndefArgs[N] = *I; + } + + badArg = true; + break; + } + + RVal V = GetRVal(St, *I); + } + + if (badArg) + continue; + + // FIXME: Eventually we will properly handle the effects of a message + // expr. For now invalidate all arguments passed in by references. + + for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end(); + I != E; ++I) { + + RVal V = GetRVal(St, *I); + + if (isa<LVal>(V)) + St = SetRVal(St, cast<LVal>(V), UnknownVal()); + } + + MakeNode(Dst, ME, *NI, St); + } return; } NodeSet Tmp; - Visit(*I, Pred, Tmp); + Visit(*AI, Pred, Tmp); - ++I; + ++AI; for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) - VisitObjCMessageExprHelper(ME, I, E, *NI, Dst); + VisitObjCMessageExprHelper(ME, AI, AE, *NI, Dst); } |