aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2011-10-24 18:26:19 +0000
committerAnna Zaks <ganna@apple.com>2011-10-24 18:26:19 +0000
commitebae6d0209e1ec3d5ea14f9e63bd0d740218ed14 (patch)
tree7271eba1485f3319db7907cc5ec2bcc2d6524509 /lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
parentd231d0130a95336610ab9a42eaeb2cdac19992f3 (diff)
[analyzer] Convert ExprEngine::visit() to use short lived builders.
This commit removes the major functional dependency on the ExprEngine::Builder member variable. In some cases the code became more verbose. Particularly, we call takeNodes() and addNodes() to move responsibility for the nodes from one builder to another. This will get simplified later on. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142831 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineObjC.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp54
1 files changed, 22 insertions, 32 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 7827873e9d..a3280ab774 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -14,7 +14,6 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
-#include "clang/Analysis/Support/SaveAndRestore.h"
using namespace clang;
using namespace ento;
@@ -22,13 +21,13 @@ using namespace ento;
void ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
-
const ProgramState *state = Pred->getState();
SVal baseVal = state->getSVal(Ex->getBase());
SVal location = state->getLValue(Ex->getDecl(), baseVal);
ExplodedNodeSet dstIvar;
- MakeNode(dstIvar, Ex, Pred, state->BindExpr(Ex, location));
+ PureStmtNodeBuilder Bldr(Pred, dstIvar, *currentBuilderContext);
+ Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, location));
// Perform the post-condition check of the ObjCIvarRefExpr and store
// the created nodes in 'Dst'.
@@ -69,10 +68,11 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
// For now: simulate (1) by assigning either a symbol or nil if the
// container is empty. Thus this transfer function will by default
// result in state splitting.
-
+
const Stmt *elem = S->getElement();
const ProgramState *state = Pred->getState();
SVal elementV;
+ PureStmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
if (const DeclStmt *DS = dyn_cast<DeclStmt>(elem)) {
const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
@@ -84,10 +84,9 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
}
ExplodedNodeSet dstLocation;
+ Bldr.takeNodes(Pred);
evalLocation(dstLocation, elem, Pred, state, elementV, NULL, false);
-
- if (dstLocation.empty())
- return;
+ Bldr.addNodes(dstLocation);
for (ExplodedNodeSet::iterator NI = dstLocation.begin(),
NE = dstLocation.end(); NI!=NE; ++NI) {
@@ -110,7 +109,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
// For now, just 'conjure' up a symbolic value.
QualType T = R->getValueType();
assert(Loc::isLocType(T));
- unsigned Count = Builder->getCurrentBlockCount();
+ unsigned Count = currentBuilderContext->getCurrentBlockCount();
SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count);
SVal V = svalBuilder.makeLoc(Sym);
hasElems = hasElems->bindLoc(elementV, V);
@@ -121,8 +120,8 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
}
// Create the new nodes.
- MakeNode(Dst, S, Pred, hasElems);
- MakeNode(Dst, S, Pred, noElems);
+ Bldr.generateNode(S, Pred, hasElems);
+ Bldr.generateNode(S, Pred, noElems);
}
}
@@ -137,14 +136,13 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
// Proceed with evaluate the message expression.
ExplodedNodeSet dstEval;
-
+ PureStmtNodeBuilder Bldr(dstPrevisit, dstEval, *currentBuilderContext);
+
for (ExplodedNodeSet::iterator DI = dstPrevisit.begin(),
DE = dstPrevisit.end(); DI != DE; ++DI) {
ExplodedNode *Pred = *DI;
bool RaisesException = false;
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
- SaveOr OldHasGen(Builder->hasGeneratedNode);
if (const Expr *Receiver = msg.getInstanceReceiver()) {
const ProgramState *state = Pred->getState();
@@ -159,7 +157,6 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
// 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.
if (nilState && !notNilState) {
- dstEval.insert(Pred);
continue;
}
@@ -168,13 +165,10 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
if (msg.getSelector() == RaiseSel)
RaisesException = true;
- // Check if we raise an exception. For now treat these as sinks.
+ // If we raise an exception, for now treat it as a sink.
// Eventually we will want to handle exceptions properly.
- if (RaisesException)
- Builder->BuildSinks = true;
-
// Dispatch to plug-in transfer function.
- evalObjCMessage(dstEval, msg, Pred, notNilState);
+ evalObjCMessage(Bldr, msg, Pred, notNilState, RaisesException);
}
}
else if (const ObjCInterfaceDecl *Iface = msg.getReceiverInterface()) {
@@ -217,16 +211,11 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
}
}
- // Check if we raise an exception. For now treat these as sinks.
+ // If we raise an exception, for now treat it as a sink.
// Eventually we will want to handle exceptions properly.
- if (RaisesException)
- Builder->BuildSinks = true;
-
// Dispatch to plug-in transfer function.
- evalObjCMessage(dstEval, msg, Pred, Pred->getState());
+ evalObjCMessage(Bldr, msg, Pred, Pred->getState(), RaisesException);
}
-
- assert(Builder->BuildSinks || Builder->hasGeneratedNodes());
}
// Finally, perform the post-condition check of the ObjCMessageExpr and store
@@ -234,11 +223,11 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
getCheckerManager().runCheckersForPostObjCMessage(Dst, dstEval, msg, *this);
}
-void ExprEngine::evalObjCMessage(ExplodedNodeSet &Dst, const ObjCMessage &msg,
+void ExprEngine::evalObjCMessage(PureStmtNodeBuilder &Bldr,
+ const ObjCMessage &msg,
ExplodedNode *Pred,
- const ProgramState *state) {
- assert (Builder && "StmtNodeBuilder must be defined.");
-
+ const ProgramState *state,
+ bool GenSink) {
// First handle the return value.
SVal ReturnValue = UnknownVal();
@@ -261,7 +250,7 @@ void ExprEngine::evalObjCMessage(ExplodedNodeSet &Dst, const ObjCMessage &msg,
if (ReturnValue.isUnknown()) {
SValBuilder &SVB = getSValBuilder();
QualType ResultTy = msg.getResultType(getContext());
- unsigned Count = Builder->getCurrentBlockCount();
+ unsigned Count = currentBuilderContext->getCurrentBlockCount();
const Expr *CurrentE = cast<Expr>(currentStmt);
ReturnValue = SVB.getConjuredSymbolVal(NULL, CurrentE, ResultTy, Count);
}
@@ -274,6 +263,7 @@ void ExprEngine::evalObjCMessage(ExplodedNodeSet &Dst, const ObjCMessage &msg,
state = invalidateArguments(state, CallOrObjCMessage(msg, state), LC);
// And create the new node.
- MakeNode(Dst, msg.getOriginExpr(), Pred, state);
+ Bldr.generateNode(msg.getOriginExpr(), Pred, state, GenSink);
+ assert(Bldr.hasGeneratedNodes());
}