Index: clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -406,11 +406,6 @@ enum Kind { BasicBRKind, PathSensitiveBRKind }; private: - using BugTypesTy = llvm::ImmutableSet; - - BugTypesTy::Factory F; - BugTypesTy BugTypes; - const Kind kind; BugReporterData& D; @@ -431,11 +426,10 @@ protected: BugReporter(BugReporterData& d, Kind k) - : BugTypes(F.getEmptySet()), kind(k), D(d) {} + : kind(k), D(d) {} public: - BugReporter(BugReporterData& d) - : BugTypes(F.getEmptySet()), kind(BasicBRKind), D(d) {} + BugReporter(BugReporterData &d) : kind(BasicBRKind), D(d) {} virtual ~BugReporter(); /// Generate and flush diagnostics for all bug reports. @@ -451,11 +445,6 @@ return D.getPathDiagnosticConsumers(); } - /// Iterator over the set of BugTypes tracked by the BugReporter. - using iterator = BugTypesTy::iterator; - iterator begin() { return BugTypes.begin(); } - iterator end() { return BugTypes.end(); } - /// Iterator over the set of BugReports tracked by the BugReporter. using EQClasses_iterator = llvm::FoldingSet::iterator; EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); } @@ -473,8 +462,6 @@ return {}; } - void Register(const BugType *BT); - /// Add the given report to the set of reports tracked by BugReporter. /// /// The reports are usually generated by the checkers. Further, they are @@ -509,8 +496,6 @@ PathSensitiveBugReporter(BugReporterData& d, ExprEngine& eng) : BugReporter(d, PathSensitiveBRKind), Eng(eng) {} - ~PathSensitiveBugReporter() override = default; - /// getGraph - Get the exploded graph created by the analysis engine /// for the analyzed method or function. const ExplodedGraph &getGraph() const; Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2221,7 +2221,9 @@ } BugReporter::~BugReporter() { - FlushReports(); + // Make sure reports are flushed. + assert(StrBugTypes.empty() && + "Destroying BugReporter before diagnostics are emitted!"); // Free the bug reports we are tracking. for (const auto I : EQClassesVector) @@ -2229,9 +2231,6 @@ } void BugReporter::FlushReports() { - if (BugTypes.isEmpty()) - return; - // We need to flush reports in deterministic order to ensure the order // of the reports is consistent between runs. for (const auto EQ : EQClassesVector) @@ -2242,9 +2241,6 @@ // FIXME: There are leaks from checkers that assume that the BugTypes they // create will be destroyed by the BugReporter. llvm::DeleteContainerSeconds(StrBugTypes); - - // Remove all references to the BugType objects. - BugTypes = F.getEmptySet(); } //===----------------------------------------------------------------------===// @@ -2658,10 +2654,6 @@ return Out; } -void BugReporter::Register(const BugType *BT) { - BugTypes = F.add(BugTypes, BT); -} - void BugReporter::emitReport(std::unique_ptr R) { if (const ExplodedNode *E = R->getErrorNode()) { // An error node must either be a sink or have a tag, otherwise @@ -2692,8 +2684,6 @@ R->Profile(ID); // Lookup the equivance class. If there isn't one, create it. - const BugType& BT = R->getBugType(); - Register(&BT); void *InsertPos; BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos); Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp =================================================================== --- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -609,6 +609,7 @@ // After all decls handled, run checkers on the entire TranslationUnit. checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR); + BR.FlushReports(); RecVisitorBR = nullptr; } @@ -766,6 +767,9 @@ if (SyntaxCheckTimer) SyntaxCheckTimer->stopTimer(); } + + BR.FlushReports(); + if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) { RunPathSensitiveChecks(D, IMode, VisitedCallees); if (IMode != ExprEngine::Inline_Minimal)