From 589273bebd44c3fcc09d2ad87b259dcaff30d299 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Mon, 9 Sep 2019 20:34:44 +0000 Subject: [PATCH] [analyzer] NFC: Simplify bug report equivalence classes to not be ilists. Use a vector of unique pointers instead. Differential Revision: https://reviews.llvm.org/D67024 llvm-svn: 371451 --- .../StaticAnalyzer/Core/BugReporter/BugReporter.h | 23 ++++++++-------------- clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 16 +++++++-------- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 7 ++++--- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 6243c8d..54aaa0b 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -72,7 +72,7 @@ using DiagnosticForConsumerMapTy = /// This class provides an interface through which checkers can create /// individual bug reports. -class BugReport : public llvm::ilist_node { +class BugReport { public: enum class Kind { Basic, PathSensitive }; @@ -465,28 +465,21 @@ class BugReportEquivClass : public llvm::FoldingSetNode { friend class BugReporter; /// List of *owned* BugReport objects. - llvm::ilist Reports; + llvm::SmallVector, 4> Reports; - void AddReport(std::unique_ptr R) { - Reports.push_back(R.release()); + void AddReport(std::unique_ptr &&R) { + Reports.push_back(std::move(R)); } public: BugReportEquivClass(std::unique_ptr R) { AddReport(std::move(R)); } + ArrayRef> getReports() const { return Reports; } + void Profile(llvm::FoldingSetNodeID& ID) const { assert(!Reports.empty()); - Reports.front().Profile(ID); + Reports.front()->Profile(ID); } - - using iterator = llvm::ilist::iterator; - using const_iterator = llvm::ilist::const_iterator; - - iterator begin() { return Reports.begin(); } - iterator end() { return Reports.end(); } - - const_iterator begin() const { return Reports.begin(); } - const_iterator end() const { return Reports.end(); } }; //===----------------------------------------------------------------------===// @@ -573,7 +566,7 @@ private: virtual BugReport * findReportInEquivalenceClass(BugReportEquivClass &eqClass, SmallVectorImpl &bugReports) { - return &*eqClass.begin(); + return eqClass.getReports()[0].get(); } protected: diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 331d737..d3dacc7 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2798,17 +2798,15 @@ struct FRIEC_WLItem { BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( BugReportEquivClass &EQ, SmallVectorImpl &bugReports) { - BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end(); - assert(I != E); - const BugType& BT = I->getBugType(); - // If we don't need to suppress any of the nodes because they are // post-dominated by a sink, simply add all the nodes in the equivalence class // to 'Nodes'. Any of the reports will serve as a "representative" report. + assert(EQ.getReports().size() > 0); + const BugType& BT = EQ.getReports()[0]->getBugType(); if (!BT.isSuppressOnSink()) { - BugReport *R = &*I; - for (auto &I : EQ) { - if (auto *PR = dyn_cast(&I)) { + BugReport *R = EQ.getReports()[0].get(); + for (auto &J : EQ.getReports()) { + if (auto *PR = dyn_cast(J.get())) { R = PR; bugReports.push_back(PR); } @@ -2824,8 +2822,8 @@ BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( // stack for very long paths. BugReport *exampleReport = nullptr; - for (; I != E; ++I) { - auto *R = dyn_cast(&*I); + for (const auto &I: EQ.getReports()) { + auto *R = dyn_cast(I.get()); if (!R) continue; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index de23a3c..2e06256 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3004,8 +3004,8 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { llvm::make_range(BR.EQClasses_begin(), BR.EQClasses_end()); for (const auto &EQ : EQClasses) { - for (const BugReport &R : EQ) { - const auto *PR = dyn_cast(&R); + for (const auto &I : EQ.getReports()) { + const auto *PR = dyn_cast(I.get()); if (!PR) continue; const ExplodedNode *EN = PR->getErrorNode(); @@ -3135,7 +3135,8 @@ std::string ExprEngine::DumpGraph(bool trim, StringRef Filename) { // Iterate through the reports and get their nodes. for (BugReporter::EQClasses_iterator EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { - const auto *R = dyn_cast(&*EI->begin()); + const auto *R = + dyn_cast(EI->getReports()[0].get()); if (!R) continue; const auto *N = const_cast(R->getErrorNode()); -- 2.7.4