diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp | 38 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CheckerManager.cpp | 5 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 27 |
3 files changed, 18 insertions, 52 deletions
diff --git a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp index f426265f67..bb266e5659 100644 --- a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp @@ -32,10 +32,6 @@ private: ExprEngine &Eng, ExplodedNode *Pred, ExplodedNodeSet &Dst) const; - - ExplodedNode *generateNode(const ProgramState *State, - ExplodedNode *Pred, const CallExpr *Statement, - StmtNodeBuilder &B, ExplodedNodeSet &Dst) const; }; } @@ -66,17 +62,6 @@ bool OSAtomicChecker::inlineCall(const CallExpr *CE, return false; } -ExplodedNode *OSAtomicChecker::generateNode(const ProgramState *State, - ExplodedNode *Pred, - const CallExpr *Statement, - StmtNodeBuilder &B, - ExplodedNodeSet &Dst) const { - ExplodedNode *N = B.generateNode(Statement, State, Pred, this); - if (N) - Dst.Add(N); - return N; -} - bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE, ExprEngine &Eng, ExplodedNode *Pred, @@ -85,7 +70,6 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE, if (CE->getNumArgs() != 3) return false; - StmtNodeBuilder &Builder = Eng.getBuilder(); ASTContext &Ctx = Eng.getContext(); const Expr *oldValueExpr = CE->getArg(0); QualType oldValueType = Ctx.getCanonicalType(oldValueExpr->getType()); @@ -134,11 +118,8 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE, state, location, &OSAtomicLoadTag, LoadTy); if (Tmp.empty()) { - // If no nodes were generated, other checkers must generated sinks. But - // since the builder state was restored, we set it manually to prevent - // auto transition. - // FIXME: there should be a better approach. - Builder.BuildSinks = true; + // If no nodes were generated, other checkers must have generated sinks. + // We return an empty Dst. return true; } @@ -189,14 +170,12 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE, stateEqual, location, val, &OSAtomicStoreTag); if (TmpStore.empty()) { - // If no nodes were generated, other checkers must generated sinks. But - // since the builder state was restored, we set it manually to prevent - // auto transition. - // FIXME: there should be a better approach. - Builder.BuildSinks = true; + // If no nodes were generated, other checkers must have generated sinks. + // We return an empty Dst. return true; } - + + PureStmtNodeBuilder B(TmpStore, Dst, Eng.getBuilderContext()); // Now bind the result of the comparison. for (ExplodedNodeSet::iterator I2 = TmpStore.begin(), E2 = TmpStore.end(); I2 != E2; ++I2) { @@ -207,7 +186,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE, QualType T = CE->getType(); if (!T->isVoidType()) Res = Eng.getSValBuilder().makeTruthVal(true, T); - generateNode(stateNew->BindExpr(CE, Res), predNew, CE, Builder, Dst); + B.generateNode(CE, predNew, stateNew->BindExpr(CE, Res), false, this); } } @@ -218,7 +197,8 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE, QualType T = CE->getType(); if (!T->isVoidType()) Res = Eng.getSValBuilder().makeTruthVal(false, CE->getType()); - generateNode(stateNotEqual->BindExpr(CE, Res), N, CE, Builder, Dst); + PureStmtNodeBuilder B(N, Dst, Eng.getBuilderContext()); + B.generateNode(CE, N, stateNotEqual->BindExpr(CE, Res), false, this); } } diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp index aac181fdb4..bb06967146 100644 --- a/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -117,7 +117,6 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, } NodeBuilder B(*PrevSet, *CurrSet, BldrCtx); - checkCtx.Eng.getBuilder().takeNodes(*PrevSet); for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end(); NI != NE; ++NI) { checkCtx.runChecker(*I, B, *NI); @@ -127,8 +126,6 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, if (CurrSet->empty()) return; - checkCtx.Eng.getBuilder().addNodes(*CurrSet); - // Update which NodeSet is the current one. PrevSet = CurrSet; } @@ -453,7 +450,6 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, } #endif - Eng.getBuilder().takeNodes(Pred); ExplodedNodeSet checkDst; NodeBuilder B(Pred, checkDst, Eng.getBuilderContext()); // Next, check if any of the EvalCall callbacks can evaluate the call. @@ -475,7 +471,6 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, if (evaluated) { anyEvaluated = true; Dst.insert(checkDst); - Eng.getBuilder().addNodes(checkDst); #ifdef NDEBUG break; // on release don't check that no other checker also evals. #endif diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 0b40c9aa4d..2806b51a8f 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -267,7 +267,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S, ExplodedNode *Pred) { ExplodedNodeSet TopDst; StmtNodeBuilder builder(Pred, TopDst, currentStmtIdx, *currentBuilderContext); - + Builder = &builder; // TODO: Use RAII to remove the unnecessary, tagged nodes. //RegisterCreatedNodes registerCreatedNodes(getGraph()); @@ -281,14 +281,10 @@ void ExprEngine::ProcessStmt(const CFGStmt S, currentStmt->getLocStart(), "Error evaluating statement"); - // A tag to track convenience transitions, which can be removed at cleanup. - static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node"); - Builder = &builder; EntryNode = Pred; const ProgramState *EntryState = EntryNode->getState(); CleanedState = EntryState; - ExplodedNode *CleanedNode = 0; // Create the cleaned state. const LocationContext *LC = EntryNode->getLocationContext(); @@ -307,21 +303,17 @@ void ExprEngine::ProcessStmt(const CFGStmt S, // Process any special transfer function for dead symbols. ExplodedNodeSet Tmp; + // A tag to track convenience transitions, which can be removed at cleanup. + static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node"); + if (!SymReaper.hasDeadSymbols()) { // Generate a CleanedNode that has the environment and store cleaned // up. Since no symbols are dead, we can optimize and not clean out // the constraint manager. - CleanedNode = - builder.generateNode(currentStmt, CleanedState, EntryNode, &cleanupTag); - Tmp.Add(CleanedNode); + PureStmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext); + Bldr.generateNode(currentStmt, EntryNode, CleanedState, false, &cleanupTag); } else { - SaveAndRestore<bool> OldSink(builder.BuildSinks); - SaveOr OldHasGen(builder.hasGeneratedNode); - - SaveAndRestore<bool> OldPurgeDeadSymbols(builder.PurgingDeadSymbols); - builder.PurgingDeadSymbols = true; - // Call checkers with the non-cleaned state so that they could query the // values of the soon to be dead symbols. ExplodedNodeSet CheckedSet; @@ -331,6 +323,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S, // For each node in CheckedSet, generate CleanedNodes that have the // environment, the store, and the constraints cleaned up but have the // user-supplied states as the predecessors. + PureStmtNodeBuilder Bldr(CheckedSet, Tmp, *currentBuilderContext); for (ExplodedNodeSet::const_iterator I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { const ProgramState *CheckerState = (*I)->getState(); @@ -350,10 +343,8 @@ void ExprEngine::ProcessStmt(const CFGStmt S, // generate a transition to that state. const ProgramState *CleanedCheckerSt = StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); - ExplodedNode *CleanedNode = builder.generateNode(currentStmt, - CleanedCheckerSt, *I, - &cleanupTag); - Tmp.Add(CleanedNode); + Bldr.generateNode(currentStmt, *I, CleanedCheckerSt, false, &cleanupTag, + ProgramPoint::PostPurgeDeadSymbolsKind); } } |