From b6b7ce4b50ecc2ae104f1bef95b18b575bc59226 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 6 Mar 2009 23:58:11 +0000 Subject: [PATCH] Create PathDiagnosticPiece subclasses PathDiagnosticEventPiece and PathDiagnosticControlFlowPiece to distinguish (in the class hierarchy) between events and control-flow diagnostic pieces. Clients must now use these directly when constructing PathDiagnosticPieces. llvm-svn: 66310 --- clang/include/clang/Analysis/PathDiagnostic.h | 43 +++++++++++++++++- clang/lib/Analysis/BugReporter.cpp | 44 ++++++++----------- clang/lib/Analysis/CFRefCount.cpp | 6 +-- clang/lib/Analysis/PathDiagnostic.cpp | 4 +- 4 files changed, 66 insertions(+), 31 deletions(-) diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h index 61c6a4094c4d..d5fa0a219245 100644 --- a/clang/include/clang/Analysis/PathDiagnostic.h +++ b/clang/include/clang/Analysis/PathDiagnostic.h @@ -190,14 +190,15 @@ private: PathDiagnosticPiece(); PathDiagnosticPiece(const PathDiagnosticPiece &P); PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P); - -public: + +protected: PathDiagnosticPiece(FullSourceLoc pos, const std::string& s, Kind k = Event, DisplayHint hint = Below); PathDiagnosticPiece(FullSourceLoc pos, const char* s, Kind k = Event, DisplayHint hint = Below); +public: virtual ~PathDiagnosticPiece(); const std::string& getString() const { return str; } @@ -244,6 +245,40 @@ public: } FullSourceLoc getLocation() const { return Pos; } + + static inline bool classof(const PathDiagnosticPiece* P) { + return true; + } +}; + +class PathDiagnosticEventPiece : public PathDiagnosticPiece { +public: + PathDiagnosticEventPiece(FullSourceLoc pos, const std::string& s) + : PathDiagnosticPiece(pos, s, Event) {} + + PathDiagnosticEventPiece(FullSourceLoc pos, const char* s) + : PathDiagnosticPiece(pos, s, Event) {} + + ~PathDiagnosticEventPiece(); + + static inline bool classof(const PathDiagnosticPiece* P) { + return P->getKind() == Event; + } +}; + +class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece { +public: + PathDiagnosticControlFlowPiece(FullSourceLoc pos, const std::string& s) + : PathDiagnosticPiece(pos, s, Event) {} + + PathDiagnosticControlFlowPiece(FullSourceLoc pos, const char* s) + : PathDiagnosticPiece(pos, s, Event) {} + + ~PathDiagnosticControlFlowPiece(); + + static inline bool classof(const PathDiagnosticPiece* P) { + return P->getKind() == ControlFlow; + } }; class PathDiagnosticMacroPiece : public PathDiagnosticPiece { @@ -262,6 +297,10 @@ public: typedef std::vector::iterator iterator; iterator begin() { return SubPieces.begin(); } iterator end() { return SubPieces.end(); } + + static inline bool classof(const PathDiagnosticPiece* P) { + return P->getKind() == Macro; + } }; } //end clang namespace diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 88887b1d6c75..12e50d346016 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -135,7 +135,7 @@ BugReport::getEndPath(BugReporter& BR, return NULL; FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager()); - PathDiagnosticPiece* P = new PathDiagnosticPiece(L, getDescription()); + PathDiagnosticPiece* P = new PathDiagnosticEventPiece(L, getDescription()); const SourceRange *Beg, *End; getRanges(BR, Beg, End); @@ -481,7 +481,7 @@ public: std::string msg = "'" + std::string(VD->getNameAsString()) + "' now aliases '" + MostRecent->getNameAsString() + "'"; - PD.push_front(new PathDiagnosticPiece(L, msg)); + PD.push_front(new PathDiagnosticEventPiece(L, msg)); } return true; @@ -643,8 +643,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, os << "Control jumps to line " << SMgr.getInstantiationLineNumber(S->getLocStart()) << ".\n"; - PD.push_front(new PathDiagnosticPiece(L, os.str(), - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, os.str())); break; } @@ -712,8 +711,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); } - PD.push_front(new PathDiagnosticPiece(L, os.str(), - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, os.str())); break; } @@ -722,8 +720,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, std::string sbuf; llvm::raw_string_ostream os(sbuf); ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); - PD.push_front(new PathDiagnosticPiece(L, os.str(), - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, os.str())); break; } @@ -737,8 +734,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, else os << "true."; - PD.push_front(new PathDiagnosticPiece(L, os.str(), - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, os.str())); break; } @@ -751,13 +747,11 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, os << "Loop condition is true. "; ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); - PD.push_front(new PathDiagnosticPiece(L, os.str(), - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, os.str())); } else - PD.push_front(new PathDiagnosticPiece(L, - "Loop condition is false. Exiting loop.", - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, + "Loop condition is false. Exiting loop.")); break; } @@ -772,24 +766,22 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, os << "Loop condition is false. "; ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); - PD.push_front(new PathDiagnosticPiece(L, os.str(), - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, os.str())); } else - PD.push_front(new PathDiagnosticPiece(L, - "Loop condition is true. Entering loop body.", - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, + "Loop condition is true. Entering loop body.")); break; } case Stmt::IfStmtClass: { if (*(Src->succ_begin()+1) == Dst) - PD.push_front(new PathDiagnosticPiece(L, "Taking false branch.", - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, + "Taking false branch.")); else - PD.push_front(new PathDiagnosticPiece(L, "Taking true branch.", - PathDiagnosticPiece::ControlFlow)); + PD.push_front(new PathDiagnosticControlFlowPiece(L, + "Taking true branch.")); break; } @@ -872,7 +864,9 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { return; if (D->empty()) { - PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription()); + PathDiagnosticPiece* piece = + new PathDiagnosticEventPiece(L, R.getDescription()); + for ( ; Beg != End; ++Beg) piece->addRange(*Beg); D->push_back(piece); } diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index 6caea59f3e40..b08bce1d58a3 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -2506,7 +2506,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N, } FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager()); - PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str()); + PathDiagnosticPiece* P = new PathDiagnosticEventPiece(Pos, os.str()); if (Expr* Exp = dyn_cast(S)) P->addRange(Exp->getSourceRange()); @@ -2655,7 +2655,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N, Stmt* S = cast(N->getLocation()).getStmt(); FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager()); - PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str()); + PathDiagnosticPiece* P = new PathDiagnosticEventPiece(Pos, os.str()); // Add the range by scanning the children of the statement for any bindings // to Sym. @@ -2844,7 +2844,7 @@ CFRefLeakReport::getEndPath(BugReporter& br, const ExplodedNode* EndN){ " +" << RV->getCount() << " (object leaked)."; - return new PathDiagnosticPiece(L, os.str()); + return new PathDiagnosticEventPiece(L, os.str()); } diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp index 49af34dc1c1e..ae53ed9dbf07 100644 --- a/clang/lib/Analysis/PathDiagnostic.cpp +++ b/clang/lib/Analysis/PathDiagnostic.cpp @@ -50,6 +50,8 @@ PathDiagnosticPiece::PathDiagnosticPiece(FullSourceLoc pos, } PathDiagnosticPiece::~PathDiagnosticPiece() {} +PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {} +PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {} PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() { for (iterator I = begin(), E = end(); I != E; ++I) delete *I; @@ -99,7 +101,7 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel, Info.FormatDiagnostic(StrC); PathDiagnosticPiece *P = - new PathDiagnosticPiece(Info.getLocation(), + new PathDiagnosticEventPiece(Info.getLocation(), std::string(StrC.begin(), StrC.end())); for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)