diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-30 20:22:09 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-30 20:22:09 +0000 |
commit | d563d3fb73879df7147b8a5302c3bf0e1402ba18 (patch) | |
tree | 4fa18655c4f5cf2bb0cf16f16f97d16dad8fbcc3 /lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | |
parent | a989aebecde3d2fd374b894e894a950b0bd9cf67 (diff) |
[analyzer] Only allow CallEvents to be created by CallEventManager.
This ensures that it is valid to reference-count any CallEvents, and we
won't accidentally try to reclaim a CallEvent that lives on the stack.
It also hides an ugly switch statement for handling CallExprs!
There should be no functionality change here.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160986 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineObjC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index e61ea79594..e3bc498b51 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -140,17 +140,20 @@ static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) { return isSubclass(Class->getSuperClass(), II); } -void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg, +void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - + CallEventManager &CEMgr = getStateManager().getCallEventManager(); + CallEventRef<ObjCMethodCall> Msg = + CEMgr.getObjCMethodCall(ME, Pred->getState(), Pred->getLocationContext()); + // Handle the previsits checks. ExplodedNodeSet dstPrevisit; getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred, - msg, *this); + *Msg, *this); ExplodedNodeSet dstGenericPrevisit; getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit, - msg, *this); + *Msg, *this); // Proceed with evaluate the message expression. ExplodedNodeSet dstEval; @@ -159,16 +162,17 @@ void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg, for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(), DE = dstGenericPrevisit.end(); DI != DE; ++DI) { ExplodedNode *Pred = *DI; + ProgramStateRef State = Pred->getState(); + CallEventRef<ObjCMethodCall> UpdatedMsg = Msg.cloneWithState(State); - if (msg.isInstanceMessage()) { - SVal recVal = msg.getReceiverSVal(); + if (UpdatedMsg->isInstanceMessage()) { + SVal recVal = UpdatedMsg->getReceiverSVal(); if (!recVal.isUndef()) { // Bifurcate the state into nil and non-nil ones. DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal); - ProgramStateRef state = Pred->getState(); ProgramStateRef notNilState, nilState; - llvm::tie(notNilState, nilState) = state->assume(receiverVal); + llvm::tie(notNilState, nilState) = State->assume(receiverVal); // There are three cases: can be nil or non-nil, must be nil, must be // non-nil. We ignore must be nil, and merge the rest two into non-nil. @@ -180,20 +184,20 @@ void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg, // Check if the "raise" message was sent. assert(notNilState); - if (msg.getSelector() == RaiseSel) { + if (Msg->getSelector() == RaiseSel) { // If we raise an exception, for now treat it as a sink. // Eventually we will want to handle exceptions properly. - Bldr.generateNode(currentStmt, Pred, Pred->getState(), true); + Bldr.generateNode(currentStmt, Pred, State, true); continue; } // Generate a transition to non-Nil state. - if (notNilState != state) + if (notNilState != State) Pred = Bldr.generateNode(currentStmt, Pred, notNilState); } } else { // Check for special class methods. - if (const ObjCInterfaceDecl *Iface = msg.getReceiverInterface()) { + if (const ObjCInterfaceDecl *Iface = Msg->getReceiverInterface()) { if (!NSExceptionII) { ASTContext &Ctx = getContext(); NSExceptionII = &Ctx.Idents.get("NSException"); @@ -222,7 +226,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg, Ctx.Selectors.getSelector(II.size(), &II[0]); } - Selector S = msg.getSelector(); + Selector S = Msg->getSelector(); bool RaisesException = false; for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i) { if (S == NSExceptionInstanceRaiseSelectors[i]) { @@ -240,16 +244,17 @@ void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg, } } } - // Evaluate the call. - defaultEvalCall(Bldr, Pred, msg); + // Evaluate the call. + defaultEvalCall(Bldr, Pred, *UpdatedMsg); } ExplodedNodeSet dstPostvisit; - getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval, msg, *this); + getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval, + *Msg, *this); // Finally, perform the post-condition check of the ObjCMessageExpr and store // the created nodes in 'Dst'. getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit, - msg, *this); + *Msg, *this); } |