diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-01-25 00:03:57 +0000 |
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-01-25 00:03:57 +0000 |
| commit | fdbcd5465818b0802a8192855523759f1540f05a (patch) | |
| tree | 4a1bfd6932b8a543ae01e708525267ae7d930ec8 /clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp | |
| parent | 37ab726d63b282300499a5f7d603a888a8e84381 (diff) | |
| download | bcm5719-llvm-fdbcd5465818b0802a8192855523759f1540f05a.tar.gz bcm5719-llvm-fdbcd5465818b0802a8192855523759f1540f05a.zip | |
[analyzer] Introduce ExprEngine::VisitObjCMessage for handling general ObjCMessages (both message expressions and property access)
and use it in ExprEngine::VisitObjCMessageExpr.
llvm-svn: 124160
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp index 6932f4a7172..9a74bd99a15 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp @@ -2300,9 +2300,16 @@ void ExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME, WL.push_back(ObjCMsgWLItem(Item.I, *NI)); } - // Now that the arguments are processed, handle the previsits checks. + // Now that the arguments are processed, handle the ObjC message. + VisitObjCMessage(ME, ArgsEvaluated, Dst); +} + +void ExprEngine::VisitObjCMessage(const ObjCMessage &msg, + ExplodedNodeSet &Src, ExplodedNodeSet& Dst) { + + // Handle the previsits checks. ExplodedNodeSet DstPrevisit; - CheckerVisitObjCMessage(ME, DstPrevisit, ArgsEvaluated, /*isPreVisit=*/true); + CheckerVisitObjCMessage(msg, DstPrevisit, Src, /*isPreVisit=*/true); // Proceed with evaluate the message expression. ExplodedNodeSet dstEval; @@ -2310,13 +2317,13 @@ void ExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME, for (ExplodedNodeSet::iterator DI = DstPrevisit.begin(), DE = DstPrevisit.end(); DI != DE; ++DI) { - Pred = *DI; + ExplodedNode *Pred = *DI; bool RaisesException = false; unsigned oldSize = dstEval.size(); SaveAndRestore<bool> OldSink(Builder->BuildSinks); SaveOr OldHasGen(Builder->hasGeneratedNode); - if (const Expr *Receiver = ME->getInstanceReceiver()) { + if (const Expr *Receiver = msg.getInstanceReceiver()) { const GRState *state = GetState(Pred); // Bifurcate the state into nil and non-nil ones. @@ -2329,13 +2336,13 @@ void ExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME, // There are three cases: can be nil or non-nil, must be nil, must be // non-nil. We handle must be nil, and merge the rest two into non-nil. if (nilState && !notNilState) { - CheckerEvalNilReceiver(ME, dstEval, nilState, Pred); + CheckerEvalNilReceiver(msg, dstEval, nilState, Pred); continue; } // Check if the "raise" message was sent. assert(notNilState); - if (ME->getSelector() == RaiseSel) + if (msg.getSelector() == RaiseSel) RaisesException = true; // Check if we raise an exception. For now treat these as sinks. @@ -2344,11 +2351,11 @@ void ExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME, Builder->BuildSinks = true; // Dispatch to plug-in transfer function. - evalObjCMessage(dstEval, ME, Pred, notNilState); + evalObjCMessage(dstEval, msg, Pred, notNilState); } - else if (ObjCInterfaceDecl *Iface = ME->getReceiverInterface()) { + else if (const ObjCInterfaceDecl *Iface = msg.getReceiverInterface()) { IdentifierInfo* ClsName = Iface->getIdentifier(); - Selector S = ME->getSelector(); + Selector S = msg.getSelector(); // Check for special instance methods. if (!NSExceptionII) { @@ -2392,19 +2399,19 @@ void ExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME, Builder->BuildSinks = true; // Dispatch to plug-in transfer function. - evalObjCMessage(dstEval, ME, Pred, Builder->GetState(Pred)); + evalObjCMessage(dstEval, msg, Pred, Builder->GetState(Pred)); } // Handle the case where no nodes where generated. Auto-generate that // contains the updated state if we aren't generating sinks. if (!Builder->BuildSinks && dstEval.size() == oldSize && !Builder->hasGeneratedNode) - MakeNode(dstEval, ME, Pred, GetState(Pred)); + MakeNode(dstEval, msg.getOriginExpr(), Pred, GetState(Pred)); } // Finally, perform the post-condition check of the ObjCMessageExpr and store // the created nodes in 'Dst'. - CheckerVisitObjCMessage(ME, Dst, dstEval, /*isPreVisit=*/false); + CheckerVisitObjCMessage(msg, Dst, dstEval, /*isPreVisit=*/false); } //===----------------------------------------------------------------------===// |

