r182426 - [analyzer; alternate edges] prune out extra edges to a subexpression where we dive-in and out of a subexpression.

Ted Kremenek kremenek at apple.com
Tue May 21 14:38:05 PDT 2013


Author: kremenek
Date: Tue May 21 16:38:05 2013
New Revision: 182426

URL: http://llvm.org/viewvc/llvm-project?rev=182426&view=rev
Log:
[analyzer;alternate edges] prune out extra edges to a subexpression where we dive-in and out of a subexpression.

Fixes <rdar://problem/13941891>.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=182426&r1=182425&r2=182426&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Tue May 21 16:38:05 2013
@@ -1950,6 +1950,18 @@ void PathPieces::dump() const {
   }
 }
 
+/// \brief Return true if X is contained by Y.
+static bool lexicalContains(ParentMap &PM,
+                            const Stmt *X,
+                            const Stmt *Y) {
+  while (X) {
+    if (X == Y)
+      return true;
+    X = PM.getParent(X);
+  }
+  return false;
+}
+
 static bool optimizeEdges(PathPieces &path, SourceManager &SM,
                           OptimizedCallsSet &OCS,
                           LocationContextMap &LCM) {
@@ -2058,10 +2070,40 @@ static bool optimizeEdges(PathPieces &pa
     // to prevent this optimization.
     //
     if (s1End && s1End == s2Start && level2) {
-      if (isIncrementOrInitInForLoop(s1End, level2) ||
-          (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End)) &&
-            !isConditionForTerminator(level2, s1End)))
-      {
+      bool removeEdge = false;
+      // Remove edges into the increment or initialization of a
+      // loop that have no interleaving event.  This means that
+      // they aren't interesting.
+      if (isIncrementOrInitInForLoop(s1End, level2))
+        removeEdge = true;
+      // Next only consider edges that are not anchored on
+      // the condition of a terminator.  This are intermediate edges
+      // that we might want to trim.
+      else if (!isConditionForTerminator(level2, s1End)) {
+        // Trim edges on expressions that are consumed by
+        // the parent expression.
+        if (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End))) {
+          removeEdge = true;          
+        }
+        // Trim edges where a lexical containment doesn't exist.
+        // For example:
+        //
+        //  X -> Y -> Z
+        //
+        // If 'Z' lexically contains Y (it is an ancestor) and
+        // 'X' does not lexically contain Y (it is a descendant OR
+        // it has no lexical relationship at all) then trim.
+        //
+        // This can eliminate edges where we dive into a subexpression
+        // and then pop back out, etc.
+        else if (s1Start && s2End &&
+                 lexicalContains(PM, s2Start, s2End) &&
+                 !lexicalContains(PM, s1End, s1Start)) {
+          removeEdge = true;
+        }
+      }
+
+      if (removeEdge) {
         PieceI->setEndLocation(PieceNextI->getEndLocation());
         path.erase(NextI);
         hasChanges = true;





More information about the cfe-commits mailing list