aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-10-29 02:09:30 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-10-29 02:09:30 +0000
commitec9227fea66c3439991fc84b0d33b0a8b4b8875e (patch)
tree00a63e0febbd41bf9bfefba51ceee84ba59cdba3 /lib/Analysis/GRExprEngine.cpp
parent607d7f6d8f21066cc48bbe2c51e6ca412a00943f (diff)
Move NullDeref and UndefDeref into their own checker.
Add a CheckLocation() interface to Checker. Now ImplicitNullDeref nodes are cached in NullDerefChecker. More cleanups follow. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85471 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp90
1 files changed, 29 insertions, 61 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 9ed5ba5d02..c0aed2306e 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -118,17 +118,20 @@ void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
ExplodedNodeSet Tmp;
ExplodedNodeSet *PrevSet = &Src;
- for (std::vector<Checker*>::iterator I = Checkers.begin(), E = Checkers.end();
- I != E; ++I) {
+ for (llvm::DenseMap<void*, Checker*>::iterator I = Checkers.begin(),
+ E = Checkers.end(); I != E; ++I) {
+
+ llvm::DenseMap<void*, Checker*>::iterator X = I;
- ExplodedNodeSet *CurrSet = (I+1 == E) ? &Dst
+ ExplodedNodeSet *CurrSet = (++X == E) ? &Dst
: (PrevSet == &Tmp) ? &Src : &Tmp;
CurrSet->clear();
- Checker *checker = *I;
+ void *tag = I->first;
+ Checker *checker = I->second;
for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
NI != NE; ++NI)
- checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, isPrevisit);
+ checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, tag, isPrevisit);
// Update which NodeSet is the current one.
PrevSet = CurrSet;
@@ -138,6 +141,21 @@ void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
// automatically.
}
+ExplodedNode *GRExprEngine::CheckerVisitLocation(Stmt *S, ExplodedNode *Pred,
+ const GRState *state, SVal V) {
+ if (Checkers.empty())
+ return Pred;
+
+ for (llvm::DenseMap<void*, Checker*>::iterator I = Checkers.begin(),
+ E = Checkers.end(); I != E; ++I) {
+ Pred = I->second->CheckLocation(S, Pred, state, V, *this);
+ if (!Pred)
+ break;
+ }
+
+ return Pred;
+}
+
//===----------------------------------------------------------------------===//
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
@@ -166,9 +184,9 @@ GRExprEngine::GRExprEngine(AnalysisManager &mgr)
GRExprEngine::~GRExprEngine() {
BR.FlushReports();
delete [] NSExceptionInstanceRaiseSelectors;
- for (std::vector<Checker*>::iterator I=Checkers.begin(), E=Checkers.end();
- I!=E; ++I)
- delete *I;
+ for (llvm::DenseMap<void*, Checker*>::iterator I=Checkers.begin(),
+ E=Checkers.end(); I!=E; ++I)
+ delete I->second;
}
//===----------------------------------------------------------------------===//
@@ -1188,58 +1206,11 @@ ExplodedNode* GRExprEngine::EvalLocation(Stmt* Ex, ExplodedNode* Pred,
SaveAndRestore<const void*> OldTag(Builder->Tag);
Builder->Tag = tag;
- // Check for loads/stores from/to undefined values.
- if (location.isUndef()) {
- ExplodedNode* N =
- Builder->generateNode(Ex, state, Pred,
- ProgramPoint::PostUndefLocationCheckFailedKind);
-
- if (N) {
- N->markAsSink();
- UndefDeref.insert(N);
- }
-
- return 0;
- }
-
- // Check for loads/stores from/to unknown locations. Treat as No-Ops.
if (location.isUnknown())
return Pred;
- // During a load, one of two possible situations arise:
- // (1) A crash, because the location (pointer) was NULL.
- // (2) The location (pointer) is not NULL, and the dereference works.
- //
- // We add these assumptions.
-
- Loc LV = cast<Loc>(location);
-
- // "Assume" that the pointer is not NULL.
- const GRState *StNotNull = state->Assume(LV, true);
-
- // "Assume" that the pointer is NULL.
- const GRState *StNull = state->Assume(LV, false);
-
- if (StNull) {
- // Use the Generic Data Map to mark in the state what lval was null.
- const SVal* PersistentLV = getBasicVals().getPersistentSVal(LV);
- StNull = StNull->set<GRState::NullDerefTag>(PersistentLV);
+ return CheckerVisitLocation(Ex, Pred, state, location);
- // We don't use "MakeNode" here because the node will be a sink
- // and we have no intention of processing it later.
- ExplodedNode* NullNode =
- Builder->generateNode(Ex, StNull, Pred,
- ProgramPoint::PostNullCheckFailedKind);
-
- if (NullNode) {
- NullNode->markAsSink();
- if (StNotNull) ImplicitNullDeref.insert(NullNode);
- else ExplicitNullDeref.insert(NullNode);
- }
- }
-
- if (!StNotNull)
- return NULL;
// FIXME: Temporarily disable out-of-bounds checking until we make
// the logic reflect recent changes to CastRegion and friends.
@@ -1282,10 +1253,6 @@ ExplodedNode* GRExprEngine::EvalLocation(Stmt* Ex, ExplodedNode* Pred,
}
}
#endif
-
- // Generate a new node indicating the checks succeed.
- return Builder->generateNode(Ex, StNotNull, Pred,
- ProgramPoint::PostLocationChecksSucceedKind);
}
//===----------------------------------------------------------------------===//
@@ -2895,7 +2862,8 @@ namespace llvm {
template<>
struct VISIBILITY_HIDDEN DOTGraphTraits<ExplodedNode*> :
public DefaultDOTGraphTraits {
-
+ // FIXME: Since we do not cache error nodes in GRExprEngine now, this does not
+ // work.
static std::string getNodeAttributes(const ExplodedNode* N, void*) {
if (GraphPrintCheckerState->isImplicitNullDeref(N) ||