From: Artem Dergachev Date: Fri, 7 Oct 2016 10:56:44 +0000 (+0000) Subject: Revert "[analyzer] Try to re-apply r283092 "Extend bug reports with extra notes" X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a7c669b6b6e527c9db1db31313c9a0cd6621d179;p=clang Revert "[analyzer] Try to re-apply r283092 "Extend bug reports with extra notes" Vector of smart pointers wasn't the thing that caused msvc crash. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@283537 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 68d26c791d..fe8aea5d82 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -266,9 +266,6 @@ private: /// \sa shouldWidenLoops Optional WidenLoops; - /// \sa shouldDisplayNotesAsEvents - Optional 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 @@ -537,14 +534,6 @@ 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 'extra-notes-as-events' option, which defaults - /// to false when unset. - bool shouldDisplayNotesAsEvents(); - public: AnalyzerOptions() : AnalysisStoreOpt(RegionStoreModel), diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index cbb4cee3ff..0ab8b29c3e 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -67,11 +67,6 @@ public: typedef VisitorList::iterator visitor_iterator; typedef SmallVector ExtraTextList; - // FIXME: We could have used a - // SmallVector> - // as NoteList, however MSVC 2013 crashes on reading this. - typedef SmallVector NoteList; - protected: friend class BugReporter; friend class BugReportEquivClass; @@ -87,8 +82,7 @@ protected: const ExplodedNode *ErrorNode; SmallVector Ranges; ExtraTextList ExtraText; - NoteList Notes; - + typedef llvm::DenseSet Symbols; typedef llvm::DenseSet Regions; @@ -183,18 +177,6 @@ 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; } @@ -263,26 +245,7 @@ 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 Ranges = {}) { - auto *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. diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 1cc3cae9d9..c34b14cbf9 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -336,7 +336,7 @@ public: class PathDiagnosticPiece : public RefCountedBaseVPTR { public: - enum Kind { ControlFlow, Event, Macro, Call, Note }; + enum Kind { ControlFlow, Event, Macro, Call }; enum DisplayHint { Above, Below }; private: @@ -452,8 +452,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const override; static bool classof(const PathDiagnosticPiece *P) { - return P->getKind() == Event || P->getKind() == Macro || - P->getKind() == Note; + return P->getKind() == Event || P->getKind() == Macro; } }; @@ -711,23 +710,6 @@ public: 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; -}; - /// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive /// diagnostic. It represents an ordered-collection of PathDiagnosticPieces, /// each which represent the pieces of the path. diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp index 27bb976a6e..78aad3940d 100644 --- a/lib/Rewrite/HTMLRewrite.cpp +++ b/lib/Rewrite/HTMLRewrite.cpp @@ -324,7 +324,6 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID, " .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; " @@ -344,12 +343,8 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID, " border-collapse: collapse; border-spacing: 0px;\n" " }\n" " td.rowname {\n" - " text-align: right;\n" - " vertical-align: top;\n" - " font-weight: bold;\n" - " color:#444444;\n" - " padding-right:2ex;\n" - " }\n" + " text-align:right; font-weight:bold; color:#444444;\n" + " padding-right:2ex; }\n" "\n\n"; // Generate header diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 86c194e8fa..54c668cd2d 100644 --- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -344,10 +344,3 @@ 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(); -} diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 9bc7470c61..1800eff76b 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -114,15 +114,15 @@ static void removeRedundantMsgs(PathPieces &path) { path.pop_front(); switch (piece->getKind()) { - case PathDiagnosticPiece::Call: + case clang::ento::PathDiagnosticPiece::Call: removeRedundantMsgs(cast(piece)->path); break; - case PathDiagnosticPiece::Macro: + case clang::ento::PathDiagnosticPiece::Macro: removeRedundantMsgs(cast(piece)->subPieces); break; - case PathDiagnosticPiece::ControlFlow: + case clang::ento::PathDiagnosticPiece::ControlFlow: break; - case PathDiagnosticPiece::Event: { + case clang::ento::PathDiagnosticPiece::Event: { if (i == N-1) break; @@ -142,8 +142,6 @@ static void removeRedundantMsgs(PathPieces &path) { } break; } - case PathDiagnosticPiece::Note: - break; } path.push_back(piece); } @@ -201,9 +199,6 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R, } case PathDiagnosticPiece::ControlFlow: break; - - case PathDiagnosticPiece::Note: - break; } pieces.push_back(piece); @@ -2559,12 +2554,6 @@ BugReport::~BugReport() { while (!interestingSymbols.empty()) { popInterestingSymbolsAndRegions(); } - - // FIXME: Replace Notes with a list of shared pointers. - for (const auto *P: Notes) { - delete P; - } - Notes.clear(); } const Decl *BugReport::getDeclWithIssue() const { @@ -3416,28 +3405,25 @@ void BugReporter::FlushReport(BugReport *exampleReport, exampleReport->getUniqueingLocation(), exampleReport->getUniqueingDecl())); - 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(MaxBugClassSize)); + MaxBugClassSize = std::max(bugReports.size(), + static_cast(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(MaxValidBugClassSize)); + MaxValidBugClassSize = std::max(bugReports.size(), + static_cast(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. @@ -3450,28 +3436,6 @@ void BugReporter::FlushReport(BugReport *exampleReport, D->setEndOfPath(std::move(piece)); } - PathPieces &Pieces = D->getMutablePieces(); - bool ShouldConvert = 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) { - const PathDiagnosticNotePiece *Piece = *I; - // FIXME: getNotes() was supposed to return a list of shared pointers, - // and then we wouldn't normally create a new piece here, - // unless ShouldConvert is set. - PathDiagnosticPiece *ConvertedPiece = - ShouldConvert - ? static_cast(new PathDiagnosticEventPiece( - Piece->getLocation(), Piece->getString())) - : static_cast(new PathDiagnosticNotePiece( - Piece->getLocation(), Piece->getString())); - for (const auto &R : Piece->getRanges()) - ConvertedPiece->addRange(R); - - Pieces.push_front(ConvertedPiece); - } - // Get the meta data. const BugReport::ExtraTextList &Meta = exampleReport->getExtraText(); for (BugReport::ExtraTextList::const_iterator i = Meta.begin(), @@ -3556,13 +3520,6 @@ LLVM_DUMP_METHOD void PathDiagnosticMacroPiece::dump() const { // 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() << "\n"; diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index f157c3dd6c..3a18956e41 100644 --- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -152,30 +152,13 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, } // Process the path. - // Maintain the counts of extra note pieces separately. - unsigned TotalPieces = path.size(); - unsigned TotalNotePieces = - std::count_if(path.begin(), path.end(), - [](const IntrusiveRefCntPtr &p) { - return isa(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(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; - } - } + 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); // Add line numbers, header, footer, etc. @@ -209,38 +192,24 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, int ColumnNumber = path.back()->getLocation().asLocation().getExpansionColumnNumber(); // Add the name of the file as an

tag. + { std::string s; llvm::raw_string_ostream os(s); os << "\n" - << "

Bug Summary

\n\n" + << "

Bug Summary

\n
\n" "\n\n"; - - // The navigation across the extra notes pieces. - unsigned NumExtraPieces = 0; - for (const auto &Piece : path) { - if (const auto *P = dyn_cast(Piece.get())) { - int LineNumber = - P->getLocation().asLocation().getExpansionLineNumber(); - int ColumnNumber = - P->getLocation().asLocation().getExpansionColumnNumber(); - os << ""; - ++NumExtraPieces; - } - } + << html::EscapeText(DirName) + << html::EscapeText(Entry->getName()) + << "\n\n" + "\n"; // Output any other meta data. @@ -416,20 +385,13 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, // 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 and extra notes should already be handled"); + llvm_unreachable("Calls 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; @@ -437,9 +399,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, os << "\n
File:" - << html::EscapeText(DirName) - << html::EscapeText(Entry->getName()) - << "
Warning:" - "line " - << LineNumber - << ", column " - << ColumnNumber - << "
" - << D.getVerboseDescription() << "
Note:" - << "line " - << LineNumber << ", column " << ColumnNumber << "
" - << P->getString() << "
Location:" + "line " + << LineNumber + << ", column " + << ColumnNumber + << "
Description:" + << D.getVerboseDescription() << "
"; - if (!SuppressIndex) { + if (max > 1) { os << ""; if (num < max) { os << ""; if (num < max) { os << "
"; os << "
1) { os << "
comparePiece(const PathDiagnosticPiece &X, } switch (X.getKind()) { - case PathDiagnosticPiece::ControlFlow: + case clang::ento::PathDiagnosticPiece::ControlFlow: return compareControlFlow(cast(X), cast(Y)); - case PathDiagnosticPiece::Event: - case PathDiagnosticPiece::Note: + case clang::ento::PathDiagnosticPiece::Event: return None; - case PathDiagnosticPiece::Macro: + case clang::ento::PathDiagnosticPiece::Macro: return compareMacro(cast(X), cast(Y)); - case PathDiagnosticPiece::Call: + case clang::ento::PathDiagnosticPiece::Call: return compareCall(cast(X), cast(Y)); } @@ -1113,10 +1110,6 @@ void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const { 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); diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index c5263ee0e5..206156ca22 100644 --- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -281,9 +281,6 @@ static void ReportPiece(raw_ostream &o, ReportMacro(o, cast(P), FM, SM, LangOpts, indent, depth); break; - case PathDiagnosticPiece::Note: - // FIXME: Extend the plist format to support those. - break; } } diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 8bd0e125b8..3b55a1d655 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -113,28 +113,16 @@ 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(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 (const auto &Piece : FlatPath) { - if (isa(Piece.get())) - continue; - - SourceLocation NoteLoc = Piece->getLocation().asLocation(); - Diag.Report(NoteLoc, NoteID) << Piece->getString() - << Piece->getRanges(); + 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(); } } }