diff options
author | Ted Kremenek <kremenek@apple.com> | 2013-05-22 18:52:35 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2013-05-22 18:52:35 +0000 |
commit | 55efcadc1c49df097823c29cf4766fa0f1e002da (patch) | |
tree | 30ee7854f7a83cfdeb0c72ed7b80b536a1c555e0 /clang/lib | |
parent | d2d2a9f17bf45c1e697576705e9124ffdbb32d02 (diff) | |
download | bcm5719-llvm-55efcadc1c49df097823c29cf4766fa0f1e002da.tar.gz bcm5719-llvm-55efcadc1c49df097823c29cf4766fa0f1e002da.zip |
[analyzer;alternate edges] remove puny edges on the same line that span less than 3 columns.
These are legitimate control-flow edges, but visually they add
no value.
Implements <rdar://problem/13941325>.
llvm-svn: 182502
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index c7814acb8c6..9663492a14c 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1962,12 +1962,77 @@ static bool lexicalContains(ParentMap &PM, return false; } +// Remove short edges on the same line less than 3 columns in difference. +static void removePunyEdges(PathPieces &path, + SourceManager &SM, + ParentMap &PM) { + + bool erased = false; + + for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; + erased ? I : ++I) { + + erased = false; + + PathDiagnosticControlFlowPiece *PieceI = + dyn_cast<PathDiagnosticControlFlowPiece>(*I); + + if (!PieceI) + continue; + + const Stmt *start = getLocStmt(PieceI->getStartLocation()); + const Stmt *end = getLocStmt(PieceI->getEndLocation()); + + if (!start || !end) + continue; + + const Stmt *endParent = PM.getParent(end); + if (!endParent) + continue; + + if (isConditionForTerminator(end, endParent)) + continue; + + bool Invalid = false; + FullSourceLoc StartL(start->getLocStart(), SM); + FullSourceLoc EndL(end->getLocStart(), SM); + + unsigned startLine = StartL.getSpellingLineNumber(&Invalid); + if (Invalid) + continue; + + unsigned endLine = EndL.getSpellingLineNumber(&Invalid); + if (Invalid) + continue; + + if (startLine != endLine) + continue; + + unsigned startCol = StartL.getSpellingColumnNumber(&Invalid); + if (Invalid) + continue; + + unsigned endCol = EndL.getSpellingColumnNumber(&Invalid); + if (Invalid) + continue; + + if (abs(startCol - endCol) <= 2) { + PathPieces::iterator PieceToErase = I; + ++I; + erased = true; + path.erase(PieceToErase); + continue; + } + } +} + static bool optimizeEdges(PathPieces &path, SourceManager &SM, OptimizedCallsSet &OCS, LocationContextMap &LCM) { bool hasChanges = false; const LocationContext *LC = LCM[&path]; assert(LC); + ParentMap &PM = LC->getParentMap(); bool isFirst = true; for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) { @@ -1995,7 +2060,6 @@ static bool optimizeEdges(PathPieces &path, SourceManager &SM, continue; } - ParentMap &PM = LC->getParentMap(); const Stmt *s1Start = getLocStmt(PieceI->getStartLocation()); const Stmt *s1End = getLocStmt(PieceI->getEndLocation()); const Stmt *level1 = getStmtParent(s1Start, PM); @@ -2132,7 +2196,11 @@ static bool optimizeEdges(PathPieces &path, SourceManager &SM, ++I; } - // No changes. + if (!hasChanges) { + // Remove any puny edges left over after primary optimization pass. + removePunyEdges(path, SM, PM); + } + return hasChanges; } |