diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-01-06 22:09:28 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-01-06 22:09:28 +0000 |
commit | 5eca482fe895ea57bc82410222e6426c09e63284 (patch) | |
tree | 1f0861024b70d405e980c0dcbed9baa0904d0913 /lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | |
parent | 0782ef2bd0ef5025ac6512cfa445a80a464c3b7f (diff) |
[analyzer] Make the entries in 'Environment' context-sensitive by making entries map from
(Stmt*,LocationContext*) pairs to SVals instead of Stmt* to SVals.
This is needed to support basic IPA via inlining. Without this, we cannot tell
if a Stmt* binding is part of the current analysis scope (StackFrameContext) or
part of a parent context.
This change introduces an uglification of the use of getSVal(), and thus takes
two steps forward and one step back. There are also potential performance implications
of enlarging the Environment. Both can be addressed going forward by refactoring the
APIs and optimizing the internal representation of Environment. This patch
mainly introduces the functionality upon when we want to build upon (and clean up).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147688 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineObjC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index a03a7b29e6..cb83d2f560 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -22,12 +22,13 @@ void ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst) { const ProgramState *state = Pred->getState(); - SVal baseVal = state->getSVal(Ex->getBase()); + const LocationContext *LCtx = Pred->getLocationContext(); + SVal baseVal = state->getSVal(Ex->getBase(), LCtx); SVal location = state->getLValue(Ex->getDecl(), baseVal); ExplodedNodeSet dstIvar; StmtNodeBuilder Bldr(Pred, dstIvar, *currentBuilderContext); - Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, location)); + Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, location)); // Perform the post-condition check of the ObjCIvarRefExpr and store // the created nodes in 'Dst'. @@ -80,7 +81,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, elementV = state->getLValue(elemD, Pred->getLocationContext()); } else { - elementV = state->getSVal(elem); + elementV = state->getSVal(elem, Pred->getLocationContext()); } ExplodedNodeSet dstLocation; @@ -92,14 +93,15 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, NE = dstLocation.end(); NI!=NE; ++NI) { Pred = *NI; const ProgramState *state = Pred->getState(); + const LocationContext *LCtx = Pred->getLocationContext(); // Handle the case where the container still has elements. SVal TrueV = svalBuilder.makeTruthVal(1); - const ProgramState *hasElems = state->BindExpr(S, TrueV); + const ProgramState *hasElems = state->BindExpr(S, LCtx, TrueV); // Handle the case where the container has no elements. SVal FalseV = svalBuilder.makeTruthVal(0); - const ProgramState *noElems = state->BindExpr(S, FalseV); + const ProgramState *noElems = state->BindExpr(S, LCtx, FalseV); if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV)) if (const TypedValueRegion *R = @@ -146,7 +148,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg, if (const Expr *Receiver = msg.getInstanceReceiver()) { const ProgramState *state = Pred->getState(); - SVal recVal = state->getSVal(Receiver); + SVal recVal = state->getSVal(Receiver, Pred->getLocationContext()); if (!recVal.isUndef()) { // Bifurcate the state into nil and non-nil ones. DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal); @@ -241,7 +243,7 @@ void ExprEngine::evalObjCMessage(StmtNodeBuilder &Bldr, // These methods return their receivers. const Expr *ReceiverE = msg.getInstanceReceiver(); if (ReceiverE) - ReturnValue = state->getSVal(ReceiverE); + ReturnValue = state->getSVal(ReceiverE, Pred->getLocationContext()); break; } } @@ -256,11 +258,11 @@ void ExprEngine::evalObjCMessage(StmtNodeBuilder &Bldr, } // Bind the return value. - state = state->BindExpr(currentStmt, ReturnValue); + const LocationContext *LCtx = Pred->getLocationContext(); + state = state->BindExpr(currentStmt, LCtx, ReturnValue); // Invalidate the arguments (and the receiver) - const LocationContext *LC = Pred->getLocationContext(); - state = invalidateArguments(state, CallOrObjCMessage(msg, state), LC); + state = invalidateArguments(state, CallOrObjCMessage(msg, state, LCtx), LCtx); // And create the new node. Bldr.generateNode(msg.getOriginExpr(), Pred, state, GenSink); |