diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-11-13 05:04:52 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-11-13 05:04:52 +0000 |
commit | 33d46268fb286fc43296f421ff835b085bb2c14f (patch) | |
tree | fe3c72affaa41a340254af1536d3cba1d82b734f /lib/Checker/IdempotentOperationChecker.cpp | |
parent | 3e47b486f200d2b4cfb069c6f0d20fe5cf189fcd (diff) |
Teach IdempotentOperations::PathWasCompletelyAnalyzed to also consider items remaining in the
worklist that could have impacted the evaluation of a block.
Fixes <rdar://problem/8663596>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118983 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/IdempotentOperationChecker.cpp')
-rw-r--r-- | lib/Checker/IdempotentOperationChecker.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/lib/Checker/IdempotentOperationChecker.cpp b/lib/Checker/IdempotentOperationChecker.cpp index 7b9ff755a7..eb6004ec05 100644 --- a/lib/Checker/IdempotentOperationChecker.cpp +++ b/lib/Checker/IdempotentOperationChecker.cpp @@ -82,6 +82,7 @@ private: const Expr *RHS); bool PathWasCompletelyAnalyzed(const CFG *C, const CFGBlock *CB, + const CFGStmtMap *CBM, const GRCoreEngine &CE); static bool CanVary(const Expr *Ex, AnalysisContext *AC); @@ -386,7 +387,7 @@ void IdempotentOperationChecker::VisitEndAnalysis(ExplodedGraph &G, // If we can trace back if (!PathWasCompletelyAnalyzed(AC->getCFG(), - CBM->getBlock(B), + CBM->getBlock(B), CBM, Eng.getCoreEngine())) continue; @@ -550,6 +551,7 @@ bool IdempotentOperationChecker::isTruncationExtensionAssignment( bool IdempotentOperationChecker::PathWasCompletelyAnalyzed( const CFG *C, const CFGBlock *CB, + const CFGStmtMap *CBM, const GRCoreEngine &CE) { // Test for reachability from any aborted blocks to this block typedef GRCoreEngine::BlocksAborted::const_iterator AbortedIterator; @@ -563,6 +565,34 @@ bool IdempotentOperationChecker::PathWasCompletelyAnalyzed( if (CRA.isReachable(BE.getDst(), CB)) return false; } + + // For the items still on the worklist, see if they are in blocks that + // can eventually reach 'CB'. + class VisitWL : public GRWorkList::Visitor { + const CFGStmtMap *CBM; + const CFGBlock *TargetBlock; + CFGReachabilityAnalysis &CRA; + public: + VisitWL(const CFGStmtMap *cbm, const CFGBlock *targetBlock, + CFGReachabilityAnalysis &cra) + : CBM(cbm), TargetBlock(targetBlock), CRA(cra) {} + virtual bool Visit(const GRWorkListUnit &U) { + ProgramPoint P = U.getNode()->getLocation(); + const CFGBlock *B = 0; + if (StmtPoint *SP = dyn_cast<StmtPoint>(&P)) { + B = CBM->getBlock(SP->getStmt()); + } + if (!B) + return true; + + return CRA.isReachable(B, TargetBlock); + } + }; + VisitWL visitWL(CBM, CB, CRA); + // Were there any items in the worklist that could potentially reach + // this block? + if (CE.getWorkList()->VisitItemsInWorkList(visitWL)) + return false; // Verify that this block is reachable from the entry block if (!CRA.isReachable(&C->getEntry(), CB)) |