From 68fbb3ee8ae374b6505885e907af92b30eef707f Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 24 Feb 2012 02:06:33 +0000 Subject: [PATCH] Revert r151317 - Rework PathDiagnostics creation.. - to appease buildbots. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151338 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/BugReporter/BugReporterVisitor.h | 17 +++ .../Core/BugReporter/PathDiagnostic.h | 82 ++++--------- lib/StaticAnalyzer/Core/BugReporter.cpp | 111 +++++------------- .../Core/BugReporterVisitors.cpp | 48 ++++++++ lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | 50 ++------ lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 80 +------------ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 82 +++++-------- 7 files changed, 161 insertions(+), 309 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index 466849be03..eda02e2fe1 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -170,6 +170,23 @@ public: llvm::raw_ostream &Out, BugReporterContext &BRC); }; + +class CallEnterExitBRVisitor : public BugReporterVisitor { + const bool showTopLevelCall; +public: + void Profile(llvm::FoldingSetNodeID &ID) const { + static int x = 0; + ID.AddPointer(&x); + } + + CallEnterExitBRVisitor(bool showTopLevel) + : showTopLevelCall(showTopLevel) {} + + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR); +}; namespace bugreporter { diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 7c5dc2e511..0df2ea1696 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_PATH_DIAGNOSTIC_H #include "clang/Basic/SourceLocation.h" -#include "clang/Analysis/ProgramPoint.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/PointerUnion.h" @@ -263,7 +262,7 @@ public: class PathDiagnosticPiece : public RefCountedBaseVPTR { public: - enum Kind { ControlFlow, Event, Macro, Call }; + enum Kind { ControlFlow, Event, Macro, CallEnter, CallExit }; enum DisplayHint { Above, Below }; private: @@ -365,53 +364,31 @@ public: return P->getKind() == Event; } }; - -class PathDiagnosticCallPiece : public PathDiagnosticPiece { - PathDiagnosticCallPiece(const Decl *callerD, - const PathDiagnosticLocation &callReturnPos) - : PathDiagnosticPiece(Call), Caller(callerD), - Callee(0), callReturn(callReturnPos) {} - - PathDiagnosticCallPiece(PathPieces &oldPath) - : PathDiagnosticPiece(Call), Caller(0), Callee(0), path(oldPath) {} - const Decl *Caller; - const Decl *Callee; +class PathDiagnosticCallEnterPiece : public PathDiagnosticSpotPiece { public: - PathDiagnosticLocation callEnter; - PathDiagnosticLocation callReturn; - PathPieces path; + PathDiagnosticCallEnterPiece(const PathDiagnosticLocation &pos, + StringRef s) + : PathDiagnosticSpotPiece(pos, s, CallEnter, false) {} - virtual ~PathDiagnosticCallPiece(); + ~PathDiagnosticCallEnterPiece(); - const Decl *getCaller() const { return Caller; } - - const Decl *getCallee() const { return Callee; } - void setCallee(const CallEnter &CE, const SourceManager &SM); - - virtual PathDiagnosticLocation getLocation() const { - return callEnter; - } - - IntrusiveRefCntPtr getCallEnterEvent() const; - IntrusiveRefCntPtr getCallExitEvent() const; + static inline bool classof(const PathDiagnosticPiece *P) { + return P->getKind() == CallEnter; + } +}; - virtual void flattenLocations() { - callEnter.flatten(); - callReturn.flatten(); - for (PathPieces::iterator I = path.begin(), - E = path.end(); I != E; ++I) (*I)->flattenLocations(); - } - - static PathDiagnosticCallPiece *construct(const ExplodedNode *N, - const CallExit &CE, - const SourceManager &SM); +class PathDiagnosticCallExitPiece : public PathDiagnosticSpotPiece { +public: + PathDiagnosticCallExitPiece(const PathDiagnosticLocation &pos, + StringRef s) + : PathDiagnosticSpotPiece(pos, s, CallExit, false) {} - static PathDiagnosticCallPiece *construct(PathPieces &pieces); + ~PathDiagnosticCallExitPiece(); static inline bool classof(const PathDiagnosticPiece *P) { - return P->getKind() == Call; - } + return P->getKind() == CallExit; + } }; class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece { @@ -502,27 +479,8 @@ class PathDiagnostic : public llvm::FoldingSetNode { std::string Desc; std::string Category; std::deque OtherDesc; - PathPieces pathImpl; - llvm::SmallVector pathStack; public: - const PathPieces &path; - - /// Return the path currently used by builders for constructing the - /// PathDiagnostic. - PathPieces &getActivePath() { - if (pathStack.empty()) - return pathImpl; - return *pathStack.back(); - } - - /// Return a mutable version of 'path'. - PathPieces &getMutablePieces() { - return pathImpl; - } - - - void pushActivePath(PathPieces *p) { pathStack.push_back(p); } - void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); } + PathPieces path; PathDiagnostic(); PathDiagnostic(StringRef bugtype, StringRef desc, @@ -547,7 +505,7 @@ public: } void flattenLocations() { - for (PathPieces::iterator I = pathImpl.begin(), E = pathImpl.end(); + for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) (*I)->flattenLocations(); } diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 0c91164045..0dbc7f115d 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -447,7 +447,7 @@ public: PathDiagnosticLocation L = PathDiagnosticLocation::createBegin(S, BR.getSourceManager(), Pred->getLocationContext()); - PD.getActivePath().push_front(new PathDiagnosticEventPiece(L, os.str())); + PD.path.push_front(new PathDiagnosticEventPiece(L, os.str())); } return true; @@ -529,32 +529,6 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, NextNode = GetPredecessorNode(N); ProgramPoint P = N->getLocation(); - - if (const CallExit *CE = dyn_cast(&P)) { - PathDiagnosticCallPiece *C = - PathDiagnosticCallPiece::construct(N, *CE, SMgr); - PD.getActivePath().push_front(C); - PD.pushActivePath(&C->path); - continue; - } - - if (const CallEnter *CE = dyn_cast(&P)) { - PD.popActivePath(); - // The current active path should never be empty. Either we - // just added a bunch of stuff to the top-level path, or - // we have a previous CallExit. If the front of the active - // path is not a PathDiagnosticCallPiece, it means that the - // path terminated within a function call. We must then take the - // current contents of the active path and place it within - // a new PathDiagnosticCallPiece. - assert(!PD.getActivePath().empty()); - PathDiagnosticCallPiece *C = - dyn_cast(PD.getActivePath().front()); - if (!C) - C = PathDiagnosticCallPiece::construct(PD.getActivePath()); - C->setCallee(*CE, SMgr); - continue; - } if (const BlockEdge *BE = dyn_cast(&P)) { const CFGBlock *Src = BE->getSrc(); @@ -585,7 +559,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, os << "Control jumps to line " << End.asLocation().getExpansionLineNumber(); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); break; } @@ -637,13 +611,13 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, break; } } - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { os << "'Default' branch taken. "; const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } @@ -655,7 +629,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, std::string sbuf; llvm::raw_string_ostream os(sbuf); PathDiagnosticLocation End = PDB.ExecutionContinues(os, N); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); break; } @@ -677,7 +651,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, if (const Stmt *S = End.asStmt()) End = PDB.getEnclosingStmtLocation(S); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); break; } @@ -700,14 +674,14 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, PathDiagnosticLocation End(B->getLHS(), SMgr, LC); PathDiagnosticLocation Start = PathDiagnosticLocation::createOperatorLoc(B, SMgr); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { os << "true"; PathDiagnosticLocation Start(B->getLHS(), SMgr, LC); PathDiagnosticLocation End = PDB.ExecutionContinues(N); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } } @@ -719,7 +693,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, os << "false"; PathDiagnosticLocation Start(B->getLHS(), SMgr, LC); PathDiagnosticLocation End = PDB.ExecutionContinues(N); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { @@ -727,7 +701,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, PathDiagnosticLocation End(B->getLHS(), SMgr, LC); PathDiagnosticLocation Start = PathDiagnosticLocation::createOperatorLoc(B, SMgr); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } } @@ -746,7 +720,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, if (const Stmt *S = End.asStmt()) End = PDB.getEnclosingStmtLocation(S); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { @@ -755,7 +729,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, if (const Stmt *S = End.asStmt()) End = PDB.getEnclosingStmtLocation(S); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, "Loop condition is false. Exiting loop")); } @@ -773,7 +747,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, if (const Stmt *S = End.asStmt()) End = PDB.getEnclosingStmtLocation(S); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, os.str())); } else { @@ -781,7 +755,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, if (const Stmt *S = End.asStmt()) End = PDB.getEnclosingStmtLocation(S); - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, "Loop condition is true. Entering loop body")); } @@ -795,10 +769,10 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, End = PDB.getEnclosingStmtLocation(S); if (*(Src->succ_begin()+1) == Dst) - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, "Taking false branch")); else - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End, + PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End, "Taking true branch")); break; @@ -812,7 +786,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, for (BugReport::visitor_iterator I = R->visitor_begin(), E = R->visitor_end(); I!=E; ++I) { if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) - PD.getActivePath().push_front(p); + PD.path.push_front(p); } } @@ -1045,7 +1019,7 @@ void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) { PrevLocClean.asLocation().getExpansionLoc()) return; - PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean)); + PD.path.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean)); PrevLoc = NewLoc; } @@ -1172,10 +1146,6 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, LCtx); EB.addEdge(Loc, true); EB.flushLocations(); - PathDiagnosticCallPiece *C = - PathDiagnosticCallPiece::construct(N, *CE, SM); - PD.getActivePath().push_front(C); - PD.pushActivePath(&C->path); break; } @@ -1186,27 +1156,6 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, N->getLocationContext()->getCurrentStackFrame()) { EB.flushLocations(); } - - // Pop the call hierarchy if we are done walking the contents - // of a function call. - if (const CallEnter *CE = dyn_cast(&P)) { - PD.popActivePath(); - // The current active path should never be empty. Either we - // just added a bunch of stuff to the top-level path, or - // we have a previous CallExit. If the front of the active - // path is not a PathDiagnosticCallPiece, it means that the - // path terminated within a function call. We must then take the - // current contents of the active path and place it within - // a new PathDiagnosticCallPiece. - assert(!PD.getActivePath().empty()); - PathDiagnosticCallPiece *C = - dyn_cast(PD.getActivePath().front()); - if (!C) - C = PathDiagnosticCallPiece::construct(PD.getActivePath()); - C->setCallee(*CE, SM); - EB.addContext(CE->getCallExpr()); - break; - } // Block edges. if (const BlockEdge *BE = dyn_cast(&P)) { @@ -1230,7 +1179,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, "Looping back to the head of the loop"); EB.addEdge(p->getLocation(), true); - PD.getActivePath().push_front(p); + PD.path.push_front(p); if (CS) { PathDiagnosticLocation BL = @@ -1272,7 +1221,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) { const PathDiagnosticLocation &Loc = p->getLocation(); EB.addEdge(Loc, true); - PD.getActivePath().push_front(p); + PD.path.push_front(p); if (const Stmt *S = Loc.asStmt()) EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt()); } @@ -1603,8 +1552,8 @@ MakeReportGraph(const ExplodedGraph* G, /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object /// and collapses PathDiagosticPieces that are expanded by macros. static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) { - typedef std::vector, - SourceLocation> > MacroStackTy; + typedef std::vector, SourceLocation> > + MacroStackTy; typedef std::vector > PiecesTy; @@ -1612,8 +1561,7 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) { MacroStackTy MacroStack; PiecesTy Pieces; - for (PathPieces::const_iterator I = PD.path.begin(), E = PD.path.end(); - I!=E; ++I) { + for (PathPieces::iterator I = PD.path.begin(), E = PD.path.end(); I!=E; ++I) { // Get the location of the PathDiagnosticPiece. const FullSourceLoc Loc = (*I)->getLocation().asLocation(); @@ -1682,13 +1630,13 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) { } // Now take the pieces and construct a new PathDiagnostic. - PD.getMutablePieces().clear(); + PD.path.clear(); for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I) { if (PathDiagnosticMacroPiece *MP = dyn_cast(*I)) if (!MP->containsEvent()) continue; - PD.getMutablePieces().push_back(*I); + PD.path.push_back(*I); } } @@ -1724,6 +1672,11 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, // Register additional node visitors. R->addVisitor(new NilReceiverBRVisitor()); R->addVisitor(new ConditionBRVisitor()); + + // If inlining is turning out, emit diagnostics for CallEnter and + // CallExit at the top level. + bool showTopLevel = Eng.getAnalysisManager().shouldInlineCall(); + R->addVisitor(new CallEnterExitBRVisitor(showTopLevel)); // Generate the very last diagnostic piece - the piece is visible before // the trace is expanded. @@ -1739,7 +1692,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, if (!LastPiece) LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R); if (LastPiece) - PD.getActivePath().push_back(LastPiece); + PD.path.push_back(LastPiece); else return; @@ -2004,7 +1957,7 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { exampleReport->getDescription()); for ( ; Beg != End; ++Beg) piece->addRange(*Beg); - D->getActivePath().push_back(piece); + D->path.push_back(piece); } PD->HandlePathDiagnostic(D.take()); diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 2980190945..4b290626c0 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -709,3 +709,51 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, return new PathDiagnosticEventPiece(Loc, Out.str()); } +static PathDiagnosticLocation getLastStmtLoc(const ExplodedNode *N, + const SourceManager &SM) { + while (N) { + ProgramPoint PP = N->getLocation(); + if (const StmtPoint *SP = dyn_cast(&PP)) + return PathDiagnosticLocation(SP->getStmt(), SM, PP.getLocationContext()); + if (N->pred_empty()) + break; + N = *N->pred_begin(); + } + return PathDiagnosticLocation(); +} + +PathDiagnosticPiece * +CallEnterExitBRVisitor::VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) { + ProgramPoint PP = N->getLocation(); + SmallString<256> buf; + llvm::raw_svector_ostream Out(buf); + PathDiagnosticLocation pos; + + if (const CallEnter *CEnter = dyn_cast(&PP)) { + const Decl *callee = CEnter->getCalleeContext()->getDecl(); + pos = PathDiagnosticLocation(CEnter->getCallExpr(), BRC.getSourceManager(), + PP.getLocationContext()); + if (isa(callee)) + Out << "Entering call to block"; + else if (const NamedDecl *ND = dyn_cast(callee)) + Out << "Entering call to '" << *ND << "'"; + StringRef msg = Out.str(); + if (msg.empty()) + return 0; + return new PathDiagnosticCallEnterPiece(pos, msg); + } + else if (const CallExit *CExit = dyn_cast(&PP)) { + const Decl *caller = CExit->getLocationContext()->getParent()->getDecl(); + pos = getLastStmtLoc(PrevN, BRC.getSourceManager()); + if (const NamedDecl *ND = dyn_cast(caller)) + Out << "Returning to '" << *ND << "'"; + else + Out << "Returning to caller"; + return new PathDiagnosticCallExitPiece(pos, Out.str()); + } + + return 0; +} diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index 8004ef45a6..e39d32db96 100644 --- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -95,31 +95,8 @@ void HTMLDiagnostics::FlushDiagnosticsImpl( } } -static void flattenPath(PathPieces &path, const PathPieces &oldPath) { - for (PathPieces::const_iterator it = oldPath.begin(), et = oldPath.end(); - it != et; ++it ) { - PathDiagnosticPiece *piece = it->getPtr(); - if (const PathDiagnosticCallPiece *call = - dyn_cast(piece)) { - IntrusiveRefCntPtr callEnter = - call->getCallEnterEvent(); - if (callEnter) - path.push_back(callEnter); - flattenPath(path, call->path); - IntrusiveRefCntPtr callExit = - call->getCallExitEvent(); - if (callExit) - path.push_back(callExit); - continue; - } - - path.push_back(piece); - } -} - void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, - SmallVectorImpl *FilesMade) { - + SmallVectorImpl *FilesMade){ // Create the HTML directory if it is missing. if (!createdDir) { createdDir = true; @@ -142,15 +119,11 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, if (noDir) return; - // First flatten out the entire path to make it easier to use. - PathPieces path; - flattenPath(path, D.path); - - const SourceManager &SMgr = (*path.begin())->getLocation().getManager(); + const SourceManager &SMgr = (*D.path.begin())->getLocation().getManager(); FileID FID; // Verify that the entire path is from the same FileID. - for (PathPieces::const_iterator I = path.begin(), E = path.end(); + for (PathPieces::const_iterator I = D.path.begin(), E = D.path.end(); I != E; ++I) { FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc(); @@ -179,11 +152,10 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, Rewriter R(const_cast(SMgr), PP.getLangOptions()); // Process the path. - unsigned n = path.size(); + unsigned n = D.path.size(); unsigned max = n; - for (PathPieces::const_reverse_iterator I = path.rbegin(), - E = path.rend(); + for (PathPieces::const_reverse_iterator I = D.path.rbegin(), E=D.path.rend(); I != E; ++I, --n) HandlePiece(R, FID, **I, n, max); @@ -228,9 +200,9 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, << html::EscapeText(Entry->getName()) << "\nLocation:" "line " - << (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber() + << (*D.path.rbegin())->getLocation().asLocation().getExpansionLineNumber() << ", column " - << (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber() + << (*D.path.rbegin())->getLocation().asLocation().getExpansionColumnNumber() << "\n" "Description:" << D.getDescription() << "\n"; @@ -268,10 +240,10 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, os << "\n\n"; os << "\n\n"; - os << "\n\n"; + os << "\n\n"; // Mark the end of the tags. os << "\n\n"; @@ -360,8 +332,8 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, const char *Kind = 0; switch (P.getKind()) { - case PathDiagnosticPiece::Call: - llvm_unreachable("Calls should already be handled"); + case PathDiagnosticPiece::CallEnter: + case PathDiagnosticPiece::CallExit: case PathDiagnosticPiece::Event: Kind = "Event"; break; case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break; // Setting Kind to "Control" is intentional. diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 9a128ff8e2..bc03a2bc30 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -51,10 +51,11 @@ PathDiagnosticPiece::PathDiagnosticPiece(Kind k, DisplayHint hint) PathDiagnosticPiece::~PathDiagnosticPiece() {} PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {} -PathDiagnosticCallPiece::~PathDiagnosticCallPiece() {} +PathDiagnosticCallEnterPiece::~PathDiagnosticCallEnterPiece() {} +PathDiagnosticCallExitPiece::~PathDiagnosticCallExitPiece() {} PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {} PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {} -PathDiagnostic::PathDiagnostic() : path(pathImpl) {} +PathDiagnostic::PathDiagnostic() {} PathPieces::~PathPieces() {} PathDiagnostic::~PathDiagnostic() {} @@ -62,8 +63,7 @@ PathDiagnostic::PathDiagnostic(StringRef bugtype, StringRef desc, StringRef category) : BugType(StripTrailingDots(bugtype)), Desc(StripTrailingDots(desc)), - Category(StripTrailingDots(category)), - path(pathImpl) {} + Category(StripTrailingDots(category)) {} void PathDiagnosticConsumer::anchor() { } @@ -421,78 +421,6 @@ void PathDiagnosticLocation::flatten() { } } - -//===----------------------------------------------------------------------===// -// Manipulation of PathDiagnosticCallPieces. -//===----------------------------------------------------------------------===// - -static PathDiagnosticLocation getLastStmtLoc(const ExplodedNode *N, - const SourceManager &SM) { - while (N) { - ProgramPoint PP = N->getLocation(); - if (const StmtPoint *SP = dyn_cast(&PP)) - return PathDiagnosticLocation(SP->getStmt(), SM, PP.getLocationContext()); - if (N->pred_empty()) - break; - N = *N->pred_begin(); - } - return PathDiagnosticLocation(); -} - -PathDiagnosticCallPiece * -PathDiagnosticCallPiece::construct(const ExplodedNode *N, - const CallExit &CE, - const SourceManager &SM) { - const Decl *caller = CE.getLocationContext()->getParent()->getDecl(); - PathDiagnosticLocation pos = getLastStmtLoc(N, SM); - return new PathDiagnosticCallPiece(caller, pos); -} - -PathDiagnosticCallPiece * -PathDiagnosticCallPiece::construct(PathPieces &path) { - PathDiagnosticCallPiece *C = new PathDiagnosticCallPiece(path); - path.clear(); - path.push_front(C); - return C; -} - -void PathDiagnosticCallPiece::setCallee(const CallEnter &CE, - const SourceManager &SM) { - const Decl *D = CE.getCalleeContext()->getDecl(); - Caller = D; - callEnter = PathDiagnosticLocation(CE.getCallExpr(), SM, - CE.getLocationContext()); -} - -IntrusiveRefCntPtr -PathDiagnosticCallPiece::getCallEnterEvent() const { - if (!Callee) - return 0; - SmallString<256> buf; - llvm::raw_svector_ostream Out(buf); - if (isa(Callee)) - Out << "Entering call to block"; - else if (const NamedDecl *ND = dyn_cast(Callee)) - Out << "Entering call to '" << *ND << "'"; - StringRef msg = Out.str(); - if (msg.empty()) - return 0; - return new PathDiagnosticEventPiece(callEnter, msg); -} - -IntrusiveRefCntPtr -PathDiagnosticCallPiece::getCallExitEvent() const { - if (!Caller) - return 0; - SmallString<256> buf; - llvm::raw_svector_ostream Out(buf); - if (const NamedDecl *ND = dyn_cast_or_null(Caller)) - Out << "Returning to '" << *ND << "'"; - else - Out << "Returning to caller"; - return new PathDiagnosticEventPiece(callReturn, Out.str()); -} - //===----------------------------------------------------------------------===// // FoldingSet profiling methods. //===----------------------------------------------------------------------===// diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index e8e80c1e4e..93bd467705 100644 --- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -240,33 +240,6 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P, Indent(o, indent); o << "\n"; } -static void ReportPiece(raw_ostream &o, - const PathDiagnosticPiece &P, - const FIDMap& FM, const SourceManager &SM, - const LangOptions &LangOpts, - unsigned indent, - bool includeControlFlow); - -static void ReportCall(raw_ostream &o, - const PathDiagnosticCallPiece &P, - const FIDMap& FM, const SourceManager &SM, - const LangOptions &LangOpts, - unsigned indent) { - - IntrusiveRefCntPtr callExit = - P.getCallExitEvent(); - if (callExit) - ReportPiece(o, *callExit, FM, SM, LangOpts, indent, true); - - for (PathPieces::const_iterator I = P.path.begin(), E = P.path.end();I!=E;++I) - ReportPiece(o, **I, FM, SM, LangOpts, indent, true); - - IntrusiveRefCntPtr callEnter = - P.getCallEnterEvent(); - if (callEnter) - ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, true); -} - static void ReportMacro(raw_ostream &o, const PathDiagnosticMacroPiece& P, const FIDMap& FM, const SourceManager &SM, @@ -275,40 +248,43 @@ static void ReportMacro(raw_ostream &o, for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end(); I!=E; ++I) { - ReportPiece(o, **I, FM, SM, LangOpts, indent, false); - } -} - -static void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P, - const FIDMap& FM, const SourceManager &SM, - const LangOptions &LangOpts) { - ReportPiece(o, P, FM, SM, LangOpts, 4, true); -} -static void ReportPiece(raw_ostream &o, - const PathDiagnosticPiece &P, - const FIDMap& FM, const SourceManager &SM, - const LangOptions &LangOpts, - unsigned indent, - bool includeControlFlow) { - switch (P.getKind()) { - case PathDiagnosticPiece::ControlFlow: - if (includeControlFlow) - ReportControlFlow(o, cast(P), FM, SM, - LangOpts, indent); - break; - case PathDiagnosticPiece::Call: - ReportCall(o, cast(P), FM, SM, LangOpts, - indent); + switch ((*I)->getKind()) { + default: break; case PathDiagnosticPiece::Event: - ReportEvent(o, cast(P), FM, SM, LangOpts, + ReportEvent(o, cast(**I), FM, SM, LangOpts, indent); break; case PathDiagnosticPiece::Macro: - ReportMacro(o, cast(P), FM, SM, LangOpts, + ReportMacro(o, cast(**I), FM, SM, LangOpts, indent); break; + } + } +} + +static void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P, + const FIDMap& FM, const SourceManager &SM, + const LangOptions &LangOpts) { + + unsigned indent = 4; + + switch (P.getKind()) { + case PathDiagnosticPiece::ControlFlow: + ReportControlFlow(o, cast(P), FM, SM, + LangOpts, indent); + break; + case PathDiagnosticPiece::CallEnter: + case PathDiagnosticPiece::CallExit: + case PathDiagnosticPiece::Event: + ReportEvent(o, cast(P), FM, SM, LangOpts, + indent); + break; + case PathDiagnosticPiece::Macro: + ReportMacro(o, cast(P), FM, SM, LangOpts, + indent); + break; } } -- 2.40.0