]> granicus.if.org Git - clang/commitdiff
[analyzer;alternate edges] remove puny edges on the same line that span less than...
authorTed Kremenek <kremenek@apple.com>
Wed, 22 May 2013 18:52:35 +0000 (18:52 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 22 May 2013 18:52:35 +0000 (18:52 +0000)
These are legitimate control-flow edges, but visually they add
no value.

Implements <rdar://problem/13941325>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182502 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/BugReporter.cpp

index c7814acb8c602a5278023410e4b108382a4df618..9663492a14cdfd88064b0ce4fe50ccefbbff9a27 100644 (file)
@@ -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;
 }