summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-03-25 02:10:28 +0000
committerTed Kremenek <kremenek@apple.com>2008-03-25 02:10:28 +0000
commit945a246ad8eb82a1ec3d01a6bdae624afab94aa9 (patch)
tree7bae59d56977492d157622ed84f4ec478c382ee2
parent7d564c3b4a901d92b7ab781aec74dd5dbab87a3d (diff)
downloadbcm5719-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.h10
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp72
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);
}
OpenPOWER on IntegriCloud