diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-04-28 04:23:15 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-04-28 04:23:15 +0000 |
commit | 8bd4d037d837e7922c3661d6158229da58a03887 (patch) | |
tree | 9fd8e0f71eb9443eed04dd7ea59827e9f0620d2e /lib/Analysis/BugReporter.cpp | |
parent | 8f08c9d83fdabb6f27c44a4dbce78487519c89eb (diff) |
BugReporter (extensive diagnostics): Clean up do...while control-flow edges, and
add "Looping back to the head of the loop" diagnostic for loops.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70285 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BugReporter.cpp')
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 397d28b6e2..8db4dfa247 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -249,9 +249,7 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { else return PathDiagnosticLocation(S, SMgr); case Stmt::DoStmtClass: - if (cast<DoStmt>(Parent)->getCond() != S) return PathDiagnosticLocation(S, SMgr); - break; case Stmt::ForStmtClass: if (cast<ForStmt>(Parent)->getBody() == S) return PathDiagnosticLocation(S, SMgr); @@ -259,7 +257,7 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { case Stmt::IfStmtClass: if (cast<IfStmt>(Parent)->getCond() != S) return PathDiagnosticLocation(S, SMgr); - break; + break; case Stmt::ObjCForCollectionStmtClass: if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S) return PathDiagnosticLocation(S, SMgr); @@ -772,7 +770,6 @@ class VISIBILITY_HIDDEN EdgeBuilder { const PathDiagnosticLocation &Containee); PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L); - void rawAddEdge(PathDiagnosticLocation NewLoc); void popLocation() { PathDiagnosticLocation L = CLocs.back(); @@ -790,6 +787,8 @@ class VISIBILITY_HIDDEN EdgeBuilder { S = CE->getCond(); else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S)) S = BE->getLHS(); + else if (const DoStmt *DS = dyn_cast<DoStmt>(S)) + S = DS->getCond(); else break; } @@ -841,6 +840,8 @@ public: addEdge(PathDiagnosticLocation(S, PDB.getSourceManager()), alwaysAdd); } + void rawAddEdge(PathDiagnosticLocation NewLoc); + void addContext(const Stmt *S); }; } // end anonymous namespace @@ -1007,14 +1008,39 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, // Block edges. if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) { const CFGBlock &Blk = *BE->getSrc(); - - if (const Stmt *Term = Blk.getTerminator()) + const Stmt *Term = Blk.getTerminator(); + + if (Term) EB.addContext(Term); + // Are we jumping to the head of a loop? Add a special diagnostic. + if (const Stmt *Loop = BE->getDst()->getLoopTarget()) { + + PathDiagnosticLocation L(Loop, PDB.getSourceManager()); + PathDiagnosticEventPiece *p = + new PathDiagnosticEventPiece(L, + "Looping back to the head of the loop"); + + EB.addEdge(p->getLocation(), true); + PD.push_front(p); + + if (!Term) { + const CompoundStmt *CS = NULL; + if (const ForStmt *FS = dyn_cast<ForStmt>(Loop)) + CS = dyn_cast<CompoundStmt>(FS->getBody()); + else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop)) + CS = dyn_cast<CompoundStmt>(WS->getBody()); + + if (CS) + EB.rawAddEdge(PathDiagnosticLocation(CS->getRBracLoc(), + PDB.getSourceManager())); + } + } + continue; } - if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) { + if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) { if (const Stmt* S = BE->getFirstStmt()) { if (IsControlFlowExpr(S)) EB.addContext(S); |