From: Ted Kremenek Date: Tue, 28 Apr 2009 04:23:15 +0000 (+0000) Subject: BugReporter (extensive diagnostics): Clean up do...while control-flow edges, and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8bd4d037d837e7922c3661d6158229da58a03887;p=clang 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 --- 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(Parent)->getCond() != S) return PathDiagnosticLocation(S, SMgr); - break; case Stmt::ForStmtClass: if (cast(Parent)->getBody() == S) return PathDiagnosticLocation(S, SMgr); @@ -259,7 +257,7 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { case Stmt::IfStmtClass: if (cast(Parent)->getCond() != S) return PathDiagnosticLocation(S, SMgr); - break; + break; case Stmt::ObjCForCollectionStmtClass: if (cast(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(S)) S = BE->getLHS(); + else if (const DoStmt *DS = dyn_cast(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(&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(Loop)) + CS = dyn_cast(FS->getBody()); + else if (const WhileStmt *WS = dyn_cast(Loop)) + CS = dyn_cast(WS->getBody()); + + if (CS) + EB.rawAddEdge(PathDiagnosticLocation(CS->getRBracLoc(), + PDB.getSourceManager())); + } + } + continue; } - if (const BlockEntrance *BE = dyn_cast(&P)) { + if (const BlockEntrance *BE = dyn_cast(&P)) { if (const Stmt* S = BE->getFirstStmt()) { if (IsControlFlowExpr(S)) EB.addContext(S);