From de7bc0d997cc69bd5c337ab82665c2f7ed989138 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 22 May 2013 18:52:35 +0000 Subject: [PATCH] [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 . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182502 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/BugReporter.cpp | 72 ++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index c7814acb8c..9663492a14 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/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(*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; } -- 2.40.0