diff options
Diffstat (limited to 'clang')
3 files changed, 33 insertions, 25 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 1afa546874b..59e26293a15 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -24,11 +24,14 @@  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; } diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 97151337a76..481a31a0451 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -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); diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index e56f1572e92..28a6d403f59 100644 --- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -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  | 

