diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-02-19 04:06:22 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-02-19 04:06:22 +0000 |
commit | 66d9edc3467c27e29188a5a31ba0a90fe5a91988 (patch) | |
tree | fee875ba4ac743bb6378b46839465d4668ee5091 /clang/lib/Analysis/GRExprEngine.cpp | |
parent | 4e1f26aad0152e319185875a2816512d706bcda0 (diff) | |
download | bcm5719-llvm-66d9edc3467c27e29188a5a31ba0a90fe5a91988.tar.gz bcm5719-llvm-66d9edc3467c27e29188a5a31ba0a90fe5a91988.zip |
Implemented simple check in <rdar://problem/6600344>: When the receiver of a
message expression is nil and the return type is struct then the returned value
is undefined or potentially garbage.
llvm-svn: 65003
Diffstat (limited to 'clang/lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index b0554151825..60bef6eb718 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -1514,8 +1514,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, SVal L = GetSVal(state, Receiver); - // Check for undefined control-flow or calls to NULL. - + // Check for undefined control-flow. if (L.isUndef()) { NodeTy* N = Builder->generateNode(ME, state, Pred); @@ -1527,6 +1526,33 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, return; } + // "Assume" that the receiver is not NULL. + bool isFeasibleNotNull = false; + Assume(state, L, true, isFeasibleNotNull); + + // "Assume" that the receiver is NULL. + bool isFeasibleNull = false; + const GRState *StNull = Assume(state, L, false, isFeasibleNull); + + if (isFeasibleNull) { + // Check if the receiver was nil and the return value a struct. + if (ME->getType()->isRecordType()) { + // The [0 ...] expressions will return garbage. Flag either an + // explicit or implicit error. Because of the structure of this + // function we currently do not bifurfacte the state graph at + // this point. + // FIXME: We should bifurcate and fill the returned struct with + // garbage. + if (NodeTy* N = Builder->generateNode(ME, StNull, Pred)) { + N->markAsSink(); + if (isFeasibleNotNull) + NilReceiverStructRetImplicit.insert(N); + else + NilReceiverStructRetExplicit.insert(N); + } + } + } + // Check if the "raise" message was sent. if (ME->getSelector() == RaiseSel) RaisesException = true; |