summaryrefslogtreecommitdiffstats
path: root/clang/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
commitcf9dbe9c201f51c5fe9d5d2be2c33db04c3a59e9 (patch)
tree350fd3193ccc1d69cf00d39012522883f52d4244 /clang/lib/Checker/IdempotentOperationChecker.cpp
parentb02788dbee7d534e4c64bb98daa9607522e49f4b (diff)
downloadbcm5719-llvm-cf9dbe9c201f51c5fe9d5d2be2c33db04c3a59e9.tar.gz
bcm5719-llvm-cf9dbe9c201f51c5fe9d5d2be2c33db04c3a59e9.zip
Teach IdempotentOperations::PathWasCompletelyAnalyzed to also consider items remaining in the
worklist that could have impacted the evaluation of a block. Fixes <rdar://problem/8663596>. llvm-svn: 118983
Diffstat (limited to 'clang/lib/Checker/IdempotentOperationChecker.cpp')
-rw-r--r--clang/lib/Checker/IdempotentOperationChecker.cpp32
1 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/Checker/IdempotentOperationChecker.cpp b/clang/lib/Checker/IdempotentOperationChecker.cpp
index 7b9ff755a77..eb6004ec059 100644
--- a/clang/lib/Checker/IdempotentOperationChecker.cpp
+++ b/clang/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))
OpenPOWER on IntegriCloud