aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/IdempotentOperationChecker.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-11-13 05:04:52 +0000
committerTed Kremenek <kremenek@apple.com>2010-11-13 05:04:52 +0000
commit33d46268fb286fc43296f421ff835b085bb2c14f (patch)
treefe3c72affaa41a340254af1536d3cba1d82b734f /lib/Checker/IdempotentOperationChecker.cpp
parent3e47b486f200d2b4cfb069c6f0d20fe5cf189fcd (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.cpp32
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))