diff options
author | Jordy Rose <jediknil@belkadan.com> | 2011-08-21 19:41:36 +0000 |
---|---|---|
committer | Jordy Rose <jediknil@belkadan.com> | 2011-08-21 19:41:36 +0000 |
commit | 500abad7edfcc2409b18dd616cdbc28a094926f5 (patch) | |
tree | 84f7afadb14c3f8d1bef7e065ea7c2df4945db71 /lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | |
parent | 7df1234c2e62b2a23dc4417e527f941c20ebe858 (diff) |
[analyzer] Migrate return value handling from CFRefCount to ExprEngine. This seems to result in a minor performance hit, but I think that will go away again once we eliminate TransferFuncs from function calls entirely.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138220 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineObjC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index 34426defec..66cef61d99 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -237,3 +237,44 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg, // the created nodes in 'Dst'. getCheckerManager().runCheckersForPostObjCMessage(Dst, dstEval, msg, *this); } + +void ExprEngine::evalObjCMessage(ExplodedNodeSet &Dst, const ObjCMessage &msg, + ExplodedNode *Pred, + const ProgramState *state) { + assert (Builder && "StmtNodeBuilder must be defined."); + + // First handle the return value. + SVal ReturnValue = UnknownVal(); + + // Some method families have known return values. + switch (msg.getMethodFamily()) { + default: + break; + case OMF_autorelease: + case OMF_retain: + case OMF_self: { + // These methods return their receivers. + // FIXME: Should OMF_init be included here? + const Expr *ReceiverE = msg.getInstanceReceiver(); + if (ReceiverE) + ReturnValue = state->getSVal(ReceiverE); + break; + } + } + + // If we failed to figure out the return value, use a conjured value instead. + if (ReturnValue.isUnknown()) { + SValBuilder &SVB = getSValBuilder(); + QualType ResultTy = msg.getResultType(getContext()); + unsigned Count = Builder->getCurrentBlockCount(); + const Expr *CurrentE = cast<Expr>(currentStmt); + ReturnValue = SVB.getConjuredSymbolVal(NULL, CurrentE, ResultTy, Count); + } + + // Bind the return value. + state = state->BindExpr(currentStmt, ReturnValue); + + // Now we can handle the other aspects of the message. + getTF().evalObjCMessage(Dst, *this, *Builder, msg, Pred, state); +} + |