]> granicus.if.org Git - clang/commitdiff
[analyzer] Refactor: Make PathDiagnosticLocation responsible for creating a valid...
authorAnna Zaks <ganna@apple.com>
Wed, 14 Sep 2011 00:25:17 +0000 (00:25 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 14 Sep 2011 00:25:17 +0000 (00:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139672 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
lib/StaticAnalyzer/Core/PathDiagnostic.cpp

index 1afa546874b35c227fffbe5d800fd68eea608d5d..59e26293a15815f158bf130c0afe83aece5cb9a6 100644 (file)
 namespace clang {
 
 class Decl;
+class LocationContext;
 class SourceManager;
 class Stmt;
 
 namespace ento {
 
+class ExplodedNode;
+
 //===----------------------------------------------------------------------===//
 // High-level interface for handlers of path-sensitive diagnostics.
 //===----------------------------------------------------------------------===//
@@ -96,6 +99,10 @@ public:
   PathDiagnosticLocation(const Stmt *s, const SourceManager &sm)
     : K(StmtK), S(s), D(0), SM(&sm) {}
 
+  /// Create a location corresponding to the next valid ExplodedNode.
+  static PathDiagnosticLocation create(const ExplodedNode* N,
+                                       const SourceManager &SM);
+
   PathDiagnosticLocation(SourceRange r, const SourceManager &sm)
     : K(RangeK), R(r), S(0), D(0), SM(&sm) {}
 
@@ -123,8 +130,6 @@ public:
     return SM != 0;
   }
 
-  const SourceManager& getSourceManager() const { assert(isValid());return *SM;}
-
   FullSourceLoc asLocation() const;
   PathDiagnosticRange asRange() const;
   const Stmt *asStmt() const { assert(isValid()); return S; }
index 97151337a76ba68045c8b971f754eeee5349c031..481a31a04518f8b3e38d532f0e0af9d85bb95be1 100644 (file)
@@ -2148,29 +2148,7 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
   // occur at an actual statement (e.g., transition between blocks; end
   // of function) so we need to walk the graph and compute a real location.
   const ExplodedNode *LeakN = EndN;
-  PathDiagnosticLocation L;
-
-  while (LeakN) {
-    ProgramPoint P = LeakN->getLocation();
-
-    if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P)) {
-      L = PathDiagnosticLocation(PS->getStmt()->getLocStart(), SMgr);
-      break;
-    }
-    else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
-      if (const Stmt *Term = BE->getSrc()->getTerminator()) {
-        L = PathDiagnosticLocation(Term->getLocStart(), SMgr);
-        break;
-      }
-    }
-
-    LeakN = LeakN->succ_empty() ? 0 : *(LeakN->succ_begin());
-  }
-
-  if (!L.isValid()) {
-    const Decl &D = EndN->getCodeDecl();
-    L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);
-  }
+  PathDiagnosticLocation L = PathDiagnosticLocation::create(LeakN, SMgr);
 
   std::string sbuf;
   llvm::raw_string_ostream os(sbuf);
index e56f1572e9233a092943b72a0ef017ddd992dcff..28a6d403f59aa957d7ee9644d0c8225cbbc1ef8c 100644 (file)
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -128,6 +129,30 @@ void PathDiagnosticClient::HandlePathDiagnostic(const PathDiagnostic *D) {
 // PathDiagnosticLocation methods.
 //===----------------------------------------------------------------------===//
 
+PathDiagnosticLocation PathDiagnosticLocation::create(const ExplodedNode* N,
+                                                      const SourceManager &SM) {
+  assert(N && "Cannot create a location with a null node.");
+
+  const ExplodedNode *NI = N;
+
+  while (NI) {
+    ProgramPoint P = NI->getLocation();
+
+    if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P)) {
+      return PathDiagnosticLocation(PS->getStmt(), SM);
+    }
+    else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      const Stmt *Term = BE->getSrc()->getTerminator();
+      assert(Term);
+      return PathDiagnosticLocation(Term, SM);
+    }
+    NI = NI->succ_empty() ? 0 : *(NI->succ_begin());
+  }
+
+  const Decl &D = N->getCodeDecl();
+  return PathDiagnosticLocation(D.getBodyRBrace(), SM);
+}
+
 FullSourceLoc PathDiagnosticLocation::asLocation() const {
   assert(isValid());
   // Note that we want a 'switch' here so that the compiler can warn us in