diff options
-rw-r--r-- | include/clang/Analysis/PathDiagnostic.h | 57 | ||||
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 44 | ||||
-rw-r--r-- | lib/Analysis/PathDiagnostic.cpp | 4 |
3 files changed, 65 insertions, 40 deletions
diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index 1481e25bbd..9c6752570d 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -54,22 +54,34 @@ private: enum Kind { Range, SingleLoc, Statement } K; SourceRange R; const Stmt *S; - const SourceManager &SM; + const SourceManager *SM; public: PathDiagnosticLocation(FullSourceLoc L) - : K(SingleLoc), R(L, L), S(0), SM(L.getManager()) {} + : K(SingleLoc), R(L, L), S(0), SM(&L.getManager()) {} PathDiagnosticLocation(const Stmt *s, const SourceManager &sm) - : K(Statement), S(s), SM(sm) {} + : K(Statement), S(s), SM(&sm) {} PathDiagnosticLocation(SourceRange r, const SourceManager &sm) - : K(Range), R(r), S(0), SM(sm) {} + : K(Range), R(r), S(0), SM(&sm) {} FullSourceLoc asLocation() const; SourceRange asRange() const; const Stmt *asStmt() const { return S ? S : 0; } }; +class PathDiagnosticLocationPair { +private: + PathDiagnosticLocation Start, End; +public: + PathDiagnosticLocationPair(const PathDiagnosticLocation &start, + const PathDiagnosticLocation &end) + : Start(start), End(end) {} + + const PathDiagnosticLocation &getStart() const { return Start; } + const PathDiagnosticLocation &getEnd() const { return End; } +}; + class PathDiagnostic { std::list<PathDiagnosticPiece*> path; unsigned Size; @@ -302,29 +314,42 @@ public: }; class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece { - FullSourceLoc StartPos; - SourceLocation EndPos; + std::vector<PathDiagnosticLocationPair> LPairs; public: - PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos, + PathDiagnosticControlFlowPiece(FullSourceLoc startPos, FullSourceLoc endPos, const std::string& s) - : PathDiagnosticPiece(s, ControlFlow), StartPos(startPos), EndPos(endPos) {} + : PathDiagnosticPiece(s, ControlFlow) { + LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos)); + } - PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos, + PathDiagnosticControlFlowPiece(FullSourceLoc startPos, FullSourceLoc endPos, const char* s) - : PathDiagnosticPiece(s, ControlFlow), StartPos(startPos), EndPos(endPos) {} + : PathDiagnosticPiece(s, ControlFlow) { + LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos)); + } - PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos) - : PathDiagnosticPiece(ControlFlow), StartPos(startPos), EndPos(endPos) {} + PathDiagnosticControlFlowPiece(FullSourceLoc startPos, FullSourceLoc endPos) + : PathDiagnosticPiece(ControlFlow) { + LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos)); + } ~PathDiagnosticControlFlowPiece(); - FullSourceLoc getStartLocation() const { return StartPos; } + FullSourceLoc getStartLocation() const { + assert(!LPairs.empty() && + "PathDiagnosticControlFlowPiece needs at least one location."); + return LPairs[0].getStart().asLocation(); + } + FullSourceLoc getEndLocation() const { - return FullSourceLoc(EndPos, - const_cast<SourceManager&>(StartPos.getManager())); + assert(!LPairs.empty() && + "PathDiagnosticControlFlowPiece needs at least one location."); + return LPairs[0].getEnd().asLocation(); } - virtual FullSourceLoc getLocation() const { return StartPos; } + void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); } + + virtual FullSourceLoc getLocation() const { return getStartLocation(); } static inline bool classof(const PathDiagnosticPiece* P) { return P->getKind() == ControlFlow; diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 6807c9f08e..f1340f4811 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -85,31 +85,31 @@ static inline Stmt* GetCurrentOrNextStmt(const ExplodedNode<GRState>* N) { // Diagnostics for 'execution continues on line XXX'. //===----------------------------------------------------------------------===// -static SourceLocation ExecutionContinues(SourceManager& SMgr, - const ExplodedNode<GRState>* N, - const Decl& D, - bool* OutHasStmt = 0) { +static FullSourceLoc ExecutionContinues(SourceManager& SMgr, + const ExplodedNode<GRState>* N, + const Decl& D, + bool* OutHasStmt = 0) { if (Stmt *S = GetNextStmt(N)) { if (OutHasStmt) *OutHasStmt = true; - return S->getLocStart(); + return FullSourceLoc(S->getLocStart(), SMgr); } else { if (OutHasStmt) *OutHasStmt = false; - return D.getBody()->getRBracLoc(); + return FullSourceLoc(D.getBody()->getRBracLoc(), SMgr); } } -static SourceLocation ExecutionContinues(llvm::raw_string_ostream& os, - SourceManager& SMgr, - const ExplodedNode<GRState>* N, - const Decl& D) { +static FullSourceLoc ExecutionContinues(llvm::raw_string_ostream& os, + SourceManager& SMgr, + const ExplodedNode<GRState>* N, + const Decl& D) { // Slow, but probably doesn't matter. if (os.str().empty()) os << ' '; bool hasStmt; - SourceLocation Loc = ExecutionContinues(SMgr, N, D, &hasStmt); + FullSourceLoc Loc = ExecutionContinues(SMgr, N, D, &hasStmt); if (hasStmt) os << "Execution continues on line " @@ -749,7 +749,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, std::string sbuf; llvm::raw_string_ostream os(sbuf); - SourceLocation End = S->getLocStart(); + FullSourceLoc End(S->getLocStart(), SMgr); os << "Control jumps to line " << SMgr.getInstantiationLineNumber(End); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, @@ -761,10 +761,10 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, // Figure out what case arm we took. std::string sbuf; llvm::raw_string_ostream os(sbuf); - SourceLocation End; + FullSourceLoc End; if (Stmt* S = Dst->getLabel()) { - End = S->getLocStart(); + End = FullSourceLoc(S->getLocStart(), SMgr); switch (S->getStmtClass()) { default: @@ -832,8 +832,8 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, case Stmt::ContinueStmtClass: { std::string sbuf; llvm::raw_string_ostream os(sbuf); - SourceLocation End = ExecutionContinues(os, SMgr, N, - getStateManager().getCodeDecl()); + FullSourceLoc End = + ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); break; @@ -849,7 +849,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, else os << "true"; - SourceLocation End = + FullSourceLoc End = ExecutionContinues(SMgr, N, getStateManager().getCodeDecl()); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, @@ -863,13 +863,13 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, llvm::raw_string_ostream os(sbuf); os << "Loop condition is true. "; - SourceLocation End = + FullSourceLoc End = ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { - SourceLocation End = + FullSourceLoc End = ExecutionContinues(SMgr, N, getStateManager().getCodeDecl()); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, "Loop condition is false. Exiting loop")); @@ -885,14 +885,14 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, llvm::raw_string_ostream os(sbuf); os << "Loop condition is false. "; - SourceLocation End = + FullSourceLoc End = ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl()); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { - SourceLocation End = + FullSourceLoc End = ExecutionContinues(SMgr, N, getStateManager().getCodeDecl()); PD.push_front(new PathDiagnosticControlFlowPiece(Start, End, @@ -903,7 +903,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, } case Stmt::IfStmtClass: { - SourceLocation End = + FullSourceLoc End = ExecutionContinues(SMgr, N, getStateManager().getCodeDecl()); if (*(Src->succ_begin()+1) == Dst) diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index dd9a0a8f46..02fe1658ad 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -147,10 +147,10 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const { case Range: break; case Statement: - return FullSourceLoc(S->getLocStart(), const_cast<SourceManager&>(SM)); + return FullSourceLoc(S->getLocStart(), const_cast<SourceManager&>(*SM)); } - return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(SM)); + return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM)); } SourceRange PathDiagnosticLocation::asRange() const { |