diff options
author | Anna Zaks <ganna@apple.com> | 2011-09-14 00:25:17 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-09-14 00:25:17 +0000 |
commit | 2c65eea947d9de6ac412a92891b158d85bcd6b01 (patch) | |
tree | 84610208f0838a8aa9e66b00847b16b0973d5f8d | |
parent | 1b2a65ca3a7fe00b503bf56ae613d084f45b12ab (diff) | |
download | bcm5719-llvm-2c65eea947d9de6ac412a92891b158d85bcd6b01.tar.gz bcm5719-llvm-2c65eea947d9de6ac412a92891b158d85bcd6b01.zip |
[analyzer] Refactor: Make PathDiagnosticLocation responsible for creating a valid object given an ExploadedNode (the same logic can be reused by other checkers).
llvm-svn: 139672
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 |