From: Ted Kremenek Date: Sat, 13 Nov 2010 05:04:52 +0000 (+0000) Subject: Teach IdempotentOperations::PathWasCompletelyAnalyzed to also consider items remainin... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=33d46268fb286fc43296f421ff835b085bb2c14f;p=clang Teach IdempotentOperations::PathWasCompletelyAnalyzed to also consider items remaining in the worklist that could have impacted the evaluation of a block. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118983 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(&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))