This patch breaks Windows: http://lab.llvm.org:8011/builders/sanitizer-windows/builds/29769/
On Mon, Oct 3, 2016 at 1:07 AM Artem Dergachev via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: dergachev > Date: Mon Oct 3 02:58:26 2016 > New Revision: 283092 > > URL: http://llvm.org/viewvc/llvm-project?rev=283092&view=rev > Log: > [analyzer] Extend bug reports with extra notes > > These diagnostics are separate from the path-sensitive engine's path notes, > and can be added manually on top of path-sensitive or path-insensitive > reports. > > The new note diagnostics would appear as note:-diagnostic on console and > as blue bubbles in scan-build. In plist files they currently do not appear, > because format needs to be discussed with plist file users. > > The analyzer option "-analyzer-config notes-as-events=true" would convert > notes to normal path notes, and put them at the beginning of the path. > This is a temporary hack to show the new notes in plist files. > > A few checkers would be updated in subsequent commits, > including tests for this new feature. > > Differential Revision: https://reviews.llvm.org/D24278 > > Modified: > cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h > cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h > > cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h > cfe/trunk/lib/Rewrite/HTMLRewrite.cpp > cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp > cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp > cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp > cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp > cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp > cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp > > Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h > (original) > +++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Mon Oct > 3 02:58:26 2016 > @@ -266,6 +266,9 @@ private: > /// \sa shouldWidenLoops > Optional<bool> WidenLoops; > > + /// \sa shouldDisplayNotesAsEvents > + Optional<bool> DisplayNotesAsEvents; > + > /// A helper function that retrieves option for a given full-qualified > /// checker name. > /// Options for checkers can be specified via 'analyzer-config' > command-line > @@ -534,6 +537,14 @@ public: > /// This is controlled by the 'widen-loops' config option. > bool shouldWidenLoops(); > > + /// Returns true if the bug reporter should transparently treat extra > note > + /// diagnostic pieces as event diagnostic pieces. Useful when the > diagnostic > + /// consumer doesn't support the extra note pieces. > + /// > + /// This is controlled by the 'notes-as-events' option, which defaults > + /// to false when unset. > + bool shouldDisplayNotesAsEvents(); > + > public: > AnalyzerOptions() : > AnalysisStoreOpt(RegionStoreModel), > > Modified: > cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h > (original) > +++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h > Mon Oct 3 02:58:26 2016 > @@ -66,6 +66,8 @@ public: > typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList; > typedef VisitorList::iterator visitor_iterator; > typedef SmallVector<StringRef, 2> ExtraTextList; > + typedef SmallVector<llvm::IntrusiveRefCntPtr<PathDiagnosticNotePiece>, > 4> > + NoteList; > > protected: > friend class BugReporter; > @@ -82,7 +84,8 @@ protected: > const ExplodedNode *ErrorNode; > SmallVector<SourceRange, 4> Ranges; > ExtraTextList ExtraText; > - > + NoteList Notes; > + > typedef llvm::DenseSet<SymbolRef> Symbols; > typedef llvm::DenseSet<const MemRegion *> Regions; > > @@ -177,6 +180,18 @@ public: > const BugType& getBugType() const { return BT; } > BugType& getBugType() { return BT; } > > + /// \brief True when the report has an execution path associated with > it. > + /// > + /// A report is said to be path-sensitive if it was thrown against a > + /// particular exploded node in the path-sensitive analysis graph. > + /// Path-sensitive reports have their intermediate path diagnostics > + /// auto-generated, perhaps with the help of checker-defined visitors, > + /// and may contain extra notes. > + /// Path-insensitive reports consist only of a single warning message > + /// in a specific location, and perhaps extra notes. > + /// Path-sensitive checkers are allowed to throw path-insensitive > reports. > + bool isPathSensitive() const { return ErrorNode != nullptr; } > + > const ExplodedNode *getErrorNode() const { return ErrorNode; } > > StringRef getDescription() const { return Description; } > @@ -245,7 +260,27 @@ public: > void setDeclWithIssue(const Decl *declWithIssue) { > DeclWithIssue = declWithIssue; > } > - > + > + /// Add new item to the list of additional notes that need to be > attached to > + /// this path-insensitive report. If you want to add extra notes to a > + /// path-sensitive report, you need to use a BugReporterVisitor because > it > + /// allows you to specify where exactly in the auto-generated path > diagnostic > + /// the extra note should appear. > + void addNote(StringRef Msg, const PathDiagnosticLocation &Pos, > + ArrayRef<SourceRange> Ranges = {}) { > + PathDiagnosticNotePiece *P = > + new PathDiagnosticNotePiece(Pos, Msg); > + > + for (const auto &R : Ranges) > + P->addRange(R); > + > + Notes.push_back(P); > + } > + > + virtual const NoteList &getNotes() { > + return Notes; > + } > + > /// \brief This allows for addition of meta data to the diagnostic. > /// > /// Currently, only the HTMLDiagnosticClient knows how to display it. > > Modified: > cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- > cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h > (original) > +++ > cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h > Mon Oct 3 02:58:26 2016 > @@ -336,7 +336,7 @@ public: > > class PathDiagnosticPiece : public RefCountedBaseVPTR { > public: > - enum Kind { ControlFlow, Event, Macro, Call }; > + enum Kind { ControlFlow, Event, Macro, Call, Note }; > enum DisplayHint { Above, Below }; > > private: > @@ -452,7 +452,8 @@ public: > void Profile(llvm::FoldingSetNodeID &ID) const override; > > static bool classof(const PathDiagnosticPiece *P) { > - return P->getKind() == Event || P->getKind() == Macro; > + return P->getKind() == Event || P->getKind() == Macro || > + P->getKind() == Note; > } > }; > > @@ -706,6 +707,23 @@ public: > } > > void dump() const override; > + > + void Profile(llvm::FoldingSetNodeID &ID) const override; > +}; > + > +class PathDiagnosticNotePiece: public PathDiagnosticSpotPiece { > +public: > + PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S, > + bool AddPosRange = true) > + : PathDiagnosticSpotPiece(Pos, S, Note, AddPosRange) {} > + > + ~PathDiagnosticNotePiece() override; > + > + static inline bool classof(const PathDiagnosticPiece *P) { > + return P->getKind() == Note; > + } > + > + void dump() const override; > > void Profile(llvm::FoldingSetNodeID &ID) const override; > }; > > Modified: cfe/trunk/lib/Rewrite/HTMLRewrite.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/HTMLRewrite.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/Rewrite/HTMLRewrite.cpp (original) > +++ cfe/trunk/lib/Rewrite/HTMLRewrite.cpp Mon Oct 3 02:58:26 2016 > @@ -324,6 +324,7 @@ void html::AddHeaderFooterInternalBuilti > " .msgT { padding:0x; spacing:0x }\n" > " .msgEvent { background-color:#fff8b4; color:#000000 }\n" > " .msgControl { background-color:#bbbbbb; color:#000000 }\n" > + " .msgNote { background-color:#ddeeff; color:#000000 }\n" > " .mrange { background-color:#dfddf3 }\n" > " .mrange { border-bottom:1px solid #6F9DBE }\n" > " .PathIndex { font-weight: bold; padding:0px 5px; " > @@ -343,8 +344,12 @@ void html::AddHeaderFooterInternalBuilti > " border-collapse: collapse; border-spacing: 0px;\n" > " }\n" > " td.rowname {\n" > - " text-align:right; font-weight:bold; color:#444444;\n" > - " padding-right:2ex; }\n" > + " text-align: right;\n" > + " vertical-align: top;\n" > + " font-weight: bold;\n" > + " color:#444444;\n" > + " padding-right:2ex;\n" > + " }\n" > "</style>\n</head>\n<body>"; > > // Generate header > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Mon Oct 3 > 02:58:26 2016 > @@ -344,3 +344,10 @@ bool AnalyzerOptions::shouldWidenLoops() > WidenLoops = getBooleanOption("widen-loops", /*Default=*/false); > return WidenLoops.getValue(); > } > + > +bool AnalyzerOptions::shouldDisplayNotesAsEvents() { > + if (!DisplayNotesAsEvents.hasValue()) > + DisplayNotesAsEvents = > + getBooleanOption("notes-as-events", /*Default=*/false); > + return DisplayNotesAsEvents.getValue(); > +} > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Mon Oct 3 02:58:26 > 2016 > @@ -112,15 +112,15 @@ static void removeRedundantMsgs(PathPiec > path.pop_front(); > > switch (piece->getKind()) { > - case clang::ento::PathDiagnosticPiece::Call: > + case PathDiagnosticPiece::Call: > removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path); > break; > - case clang::ento::PathDiagnosticPiece::Macro: > + case PathDiagnosticPiece::Macro: > > removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces); > break; > - case clang::ento::PathDiagnosticPiece::ControlFlow: > + case PathDiagnosticPiece::ControlFlow: > break; > - case clang::ento::PathDiagnosticPiece::Event: { > + case PathDiagnosticPiece::Event: { > if (i == N-1) > break; > > @@ -140,6 +140,8 @@ static void removeRedundantMsgs(PathPiec > } > break; > } > + case PathDiagnosticPiece::Note: > + break; > } > path.push_back(piece); > } > @@ -197,6 +199,9 @@ static bool removeUnneededCalls(PathPiec > } > case PathDiagnosticPiece::ControlFlow: > break; > + > + case PathDiagnosticPiece::Note: > + break; > } > > pieces.push_back(piece); > @@ -3403,25 +3408,28 @@ void BugReporter::FlushReport(BugReport > exampleReport->getUniqueingLocation(), > exampleReport->getUniqueingDecl())); > > - MaxBugClassSize = std::max(bugReports.size(), > - static_cast<size_t>(MaxBugClassSize)); > + if (exampleReport->isPathSensitive()) { > + // Generate the full path diagnostic, using the generation scheme > + // specified by the PathDiagnosticConsumer. Note that we have to > generate > + // path diagnostics even for consumers which do not support paths, > because > + // the BugReporterVisitors may mark this bug as a false positive. > + assert(!bugReports.empty()); > + > + MaxBugClassSize = > + std::max(bugReports.size(), static_cast<size_t>(MaxBugClassSize)); > > - // Generate the full path diagnostic, using the generation scheme > - // specified by the PathDiagnosticConsumer. Note that we have to > generate > - // path diagnostics even for consumers which do not support paths, > because > - // the BugReporterVisitors may mark this bug as a false positive. > - if (!bugReports.empty()) > if (!generatePathDiagnostic(*D.get(), PD, bugReports)) > return; > > - MaxValidBugClassSize = std::max(bugReports.size(), > - > static_cast<size_t>(MaxValidBugClassSize)); > + MaxValidBugClassSize = > + std::max(bugReports.size(), > static_cast<size_t>(MaxValidBugClassSize)); > > - // Examine the report and see if the last piece is in a header. Reset > the > - // report location to the last piece in the main source file. > - AnalyzerOptions& Opts = getAnalyzerOptions(); > - if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll) > - D->resetDiagnosticLocationToMainFile(); > + // Examine the report and see if the last piece is in a header. Reset > the > + // report location to the last piece in the main source file. > + AnalyzerOptions &Opts = getAnalyzerOptions(); > + if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll) > + D->resetDiagnosticLocationToMainFile(); > + } > > // If the path is empty, generate a single step path with the location > // of the issue. > @@ -3434,6 +3442,27 @@ void BugReporter::FlushReport(BugReport > D->setEndOfPath(std::move(piece)); > } > > + PathPieces &Pieces = D->getMutablePieces(); > + if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) { > + // For path diagnostic consumers that don't support extra notes, > + // we may optionally convert those to path notes. > + for (auto I = exampleReport->getNotes().rbegin(), > + E = exampleReport->getNotes().rend(); I != E; ++I) { > + PathDiagnosticNotePiece *Piece = I->get(); > + PathDiagnosticEventPiece *ConvertedPiece = > + new PathDiagnosticEventPiece(Piece->getLocation(), > + Piece->getString()); > + for (const auto &R: Piece->getRanges()) > + ConvertedPiece->addRange(R); > + > + Pieces.push_front(ConvertedPiece); > + } > + } else { > + for (auto I = exampleReport->getNotes().rbegin(), > + E = exampleReport->getNotes().rend(); I != E; ++I) > + Pieces.push_front(*I); > + } > + > // Get the meta data. > const BugReport::ExtraTextList &Meta = exampleReport->getExtraText(); > for (BugReport::ExtraTextList::const_iterator i = Meta.begin(), > @@ -3518,6 +3547,13 @@ LLVM_DUMP_METHOD void PathDiagnosticMacr > // FIXME: Print which macro is being invoked. > } > > +LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump() const { > + llvm::errs() << "NOTE\n--------------\n"; > + llvm::errs() << getString() << "\n"; > + llvm::errs() << " ---- at ----\n"; > + getLocation().dump(); > +} > + > LLVM_DUMP_METHOD void PathDiagnosticLocation::dump() const { > if (!isValid()) { > llvm::errs() << "<INVALID>\n"; > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp Mon Oct 3 > 02:58:26 2016 > @@ -152,13 +152,30 @@ void HTMLDiagnostics::ReportDiag(const P > } > > // Process the path. > - unsigned n = path.size(); > - unsigned max = n; > - > - for (PathPieces::const_reverse_iterator I = path.rbegin(), > - E = path.rend(); > - I != E; ++I, --n) > - HandlePiece(R, FID, **I, n, max); > + // Maintain the counts of extra note pieces separately. > + unsigned TotalPieces = path.size(); > + unsigned TotalNotePieces = > + std::count_if(path.begin(), path.end(), > + [](const IntrusiveRefCntPtr<PathDiagnosticPiece> &p) { > + return isa<PathDiagnosticNotePiece>(p.get()); > + }); > + > + unsigned TotalRegularPieces = TotalPieces - TotalNotePieces; > + unsigned NumRegularPieces = TotalRegularPieces; > + unsigned NumNotePieces = TotalNotePieces; > + > + for (auto I = path.rbegin(), E = path.rend(); I != E; ++I) { > + if (isa<PathDiagnosticNotePiece>(I->get())) { > + // This adds diagnostic bubbles, but not navigation. > + // Navigation through note pieces would be added later, > + // as a separate pass through the piece list. > + HandlePiece(R, FID, **I, NumNotePieces, TotalNotePieces); > + --NumNotePieces; > + } else { > + HandlePiece(R, FID, **I, NumRegularPieces, TotalRegularPieces); > + --NumRegularPieces; > + } > + } > > // Add line numbers, header, footer, etc. > > @@ -192,24 +209,38 @@ void HTMLDiagnostics::ReportDiag(const P > int ColumnNumber = > path.back()->getLocation().asLocation().getExpansionColumnNumber(); > > // Add the name of the file as an <h1> tag. > - > { > std::string s; > llvm::raw_string_ostream os(s); > > os << "<!-- REPORTHEADER -->\n" > - << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n" > + << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n" > "<tr><td class=\"rowname\">File:</td><td>" > - << html::EscapeText(DirName) > - << html::EscapeText(Entry->getName()) > - << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>" > - "<a href=\"#EndPath\">line " > - << LineNumber > - << ", column " > - << ColumnNumber > - << "</a></td></tr>\n" > - "<tr><td class=\"rowname\">Description:</td><td>" > - << D.getVerboseDescription() << "</td></tr>\n"; > + << html::EscapeText(DirName) > + << html::EscapeText(Entry->getName()) > + << "</td></tr>\n<tr><td class=\"rowname\">Warning:</td><td>" > + "<a href=\"#EndPath\">line " > + << LineNumber > + << ", column " > + << ColumnNumber > + << "</a><br />" > + << D.getVerboseDescription() << "</td></tr>\n"; > + > + // The navigation across the extra notes pieces. > + unsigned NumExtraPieces = 0; > + for (const auto &Piece : path) { > + if (const auto *P = dyn_cast<PathDiagnosticNotePiece>(Piece.get())) > { > + int LineNumber = > + P->getLocation().asLocation().getExpansionLineNumber(); > + int ColumnNumber = > + P->getLocation().asLocation().getExpansionColumnNumber(); > + os << "<tr><td class=\"rowname\">Note:</td><td>" > + << "<a href=\"#Note" << NumExtraPieces << "\">line " > + << LineNumber << ", column " << ColumnNumber << "</a><br />" > + << P->getString() << "</td></tr>"; > + ++NumExtraPieces; > + } > + } > > // Output any other meta data. > > @@ -385,13 +416,20 @@ void HTMLDiagnostics::HandlePiece(Rewrit > // Create the html for the message. > > const char *Kind = nullptr; > + bool IsNote = false; > + bool SuppressIndex = (max == 1); > switch (P.getKind()) { > case PathDiagnosticPiece::Call: > - llvm_unreachable("Calls should already be handled"); > + llvm_unreachable("Calls and extra notes should already be handled"); > case PathDiagnosticPiece::Event: Kind = "Event"; break; > case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break; > // Setting Kind to "Control" is intentional. > case PathDiagnosticPiece::Macro: Kind = "Control"; break; > + case PathDiagnosticPiece::Note: > + Kind = "Note"; > + IsNote = true; > + SuppressIndex = true; > + break; > } > > std::string sbuf; > @@ -399,7 +437,9 @@ void HTMLDiagnostics::HandlePiece(Rewrit > > os << "\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\""; > > - if (num == max) > + if (IsNote) > + os << "Note" << num; > + else if (num == max) > os << "EndPath"; > else > os << "Path" << num; > @@ -461,7 +501,7 @@ void HTMLDiagnostics::HandlePiece(Rewrit > > os << "\">"; > > - if (max > 1) { > + if (!SuppressIndex) { > os << "<table class=\"msgT\"><tr><td valign=\"top\">"; > os << "<div class=\"PathIndex"; > if (Kind) os << " PathIndex" << Kind; > @@ -501,7 +541,7 @@ void HTMLDiagnostics::HandlePiece(Rewrit > > os << "':\n"; > > - if (max > 1) { > + if (!SuppressIndex) { > os << "</td>"; > if (num < max) { > os << "<td><div class=\"PathNav\"><a href=\"#"; > @@ -523,7 +563,7 @@ void HTMLDiagnostics::HandlePiece(Rewrit > else { > os << html::EscapeText(P.getString()); > > - if (max > 1) { > + if (!SuppressIndex) { > os << "</td>"; > if (num < max) { > os << "<td><div class=\"PathNav\"><a href=\"#"; > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Mon Oct 3 > 02:58:26 2016 > @@ -60,6 +60,7 @@ PathDiagnosticEventPiece::~PathDiagnosti > PathDiagnosticCallPiece::~PathDiagnosticCallPiece() {} > PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {} > PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {} > +PathDiagnosticNotePiece::~PathDiagnosticNotePiece() {} > > void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current, > bool ShouldFlattenMacros) const { > @@ -95,6 +96,7 @@ void PathPieces::flattenTo(PathPieces &P > } > case PathDiagnosticPiece::Event: > case PathDiagnosticPiece::ControlFlow: > + case PathDiagnosticPiece::Note: > Current.push_back(Piece); > break; > } > @@ -342,15 +344,16 @@ static Optional<bool> comparePiece(const > } > > switch (X.getKind()) { > - case clang::ento::PathDiagnosticPiece::ControlFlow: > + case PathDiagnosticPiece::ControlFlow: > return compareControlFlow(cast<PathDiagnosticControlFlowPiece>(X), > cast<PathDiagnosticControlFlowPiece>(Y)); > - case clang::ento::PathDiagnosticPiece::Event: > + case PathDiagnosticPiece::Event: > + case PathDiagnosticPiece::Note: > return None; > - case clang::ento::PathDiagnosticPiece::Macro: > + case PathDiagnosticPiece::Macro: > return compareMacro(cast<PathDiagnosticMacroPiece>(X), > cast<PathDiagnosticMacroPiece>(Y)); > - case clang::ento::PathDiagnosticPiece::Call: > + case PathDiagnosticPiece::Call: > return compareCall(cast<PathDiagnosticCallPiece>(X), > cast<PathDiagnosticCallPiece>(Y)); > } > @@ -1098,6 +1101,10 @@ void PathDiagnosticMacroPiece::Profile(l > ID.Add(**I); > } > > +void PathDiagnosticNotePiece::Profile(llvm::FoldingSetNodeID &ID) const { > + PathDiagnosticSpotPiece::Profile(ID); > +} > + > void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const { > ID.Add(getLocation()); > ID.AddString(BugType); > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Mon Oct 3 > 02:58:26 2016 > @@ -281,6 +281,9 @@ static void ReportPiece(raw_ostream &o, > ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), FM, SM, LangOpts, > indent, depth); > break; > + case PathDiagnosticPiece::Note: > + // FIXME: Extend the plist format to support those. > + break; > } > } > > > Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=283092&r1=283091&r2=283092&view=diff > > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Mon Oct 3 > 02:58:26 2016 > @@ -113,16 +113,28 @@ public: > Diag.Report(WarnLoc, WarnID) << PD->getShortDescription() > << PD->path.back()->getRanges(); > > + // First, add extra notes, even if paths should not be included. > + for (const auto &Piece : PD->path) { > + if (!isa<PathDiagnosticNotePiece>(Piece.get())) > + continue; > + > + SourceLocation NoteLoc = Piece->getLocation().asLocation(); > + Diag.Report(NoteLoc, NoteID) << Piece->getString() > + << Piece->getRanges(); > + } > + > if (!IncludePath) > continue; > > + // Then, add the path notes if necessary. > PathPieces FlatPath = > PD->path.flatten(/*ShouldFlattenMacros=*/true); > - for (PathPieces::const_iterator PI = FlatPath.begin(), > - PE = FlatPath.end(); > - PI != PE; ++PI) { > - SourceLocation NoteLoc = (*PI)->getLocation().asLocation(); > - Diag.Report(NoteLoc, NoteID) << (*PI)->getString() > - << (*PI)->getRanges(); > + for (const auto &Piece : FlatPath) { > + if (isa<PathDiagnosticNotePiece>(Piece.get())) > + continue; > + > + SourceLocation NoteLoc = Piece->getLocation().asLocation(); > + Diag.Report(NoteLoc, NoteID) << Piece->getString() > + << Piece->getRanges(); > } > } > } > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits