From 4a5f724538cbc275370c9504e8169ce92503256c Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 1 Apr 2012 19:30:51 +0000 Subject: [PATCH] Analyzer: Store BugReports directly in a ilist instead of adding another layer of inderection with std::list git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153847 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/BugReporter/BugReporter.h | 67 ++++++++++--------- .../Checkers/UnreachableCodeChecker.cpp | 2 +- lib/StaticAnalyzer/Core/BugReporter.cpp | 22 +++--- lib/StaticAnalyzer/Core/ExprEngine.cpp | 4 +- .../Core/ExprEngineCallAndReturn.cpp | 3 +- 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 57ffea99dd..bca28c00e1 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -20,11 +20,10 @@ #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/ImmutableList.h" +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ImmutableSet.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/DenseSet.h" -#include namespace clang { @@ -50,7 +49,7 @@ class BugType; /// This class provides an interface through which checkers can create /// individual bug reports. -class BugReport { +class BugReport : public llvm::ilist_node { public: class NodeResolver { virtual void anchor(); @@ -208,13 +207,38 @@ public: virtual void Profile(llvm::FoldingSetNodeID& hash) const; }; +} // end ento namespace +} // end clang namespace + +namespace llvm { + template<> struct ilist_traits + : public ilist_default_traits { + clang::ento::BugReport *createSentinel() const { + return static_cast(&Sentinel); + } + void destroySentinel(clang::ento::BugReport *) const {} + + clang::ento::BugReport *provideInitialHead() const { + return createSentinel(); + } + clang::ento::BugReport *ensureHead(clang::ento::BugReport *) const { + return createSentinel(); + } + private: + mutable ilist_half_node Sentinel; + }; +} + +namespace clang { +namespace ento { + //===----------------------------------------------------------------------===// // BugTypes (collections of related reports). //===----------------------------------------------------------------------===// class BugReportEquivClass : public llvm::FoldingSetNode { /// List of *owned* BugReport objects. - std::list Reports; + llvm::ilist Reports; friend class BugReporter; void AddReport(BugReport* R) { Reports.push_back(R); } @@ -224,36 +248,17 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const { assert(!Reports.empty()); - (*Reports.begin())->Profile(ID); + Reports.front().Profile(ID); } - class iterator { - std::list::iterator impl; - public: - iterator(std::list::iterator i) : impl(i) {} - iterator &operator++() { ++impl; return *this; } - bool operator==(const iterator &I) const { return I.impl == impl; } - bool operator!=(const iterator &I) const { return I.impl != impl; } - BugReport* operator*() const { return *impl; } - BugReport* operator->() const { return *impl; } - }; - - class const_iterator { - std::list::const_iterator impl; - public: - const_iterator(std::list::const_iterator i) : impl(i) {} - const_iterator &operator++() { ++impl; return *this; } - bool operator==(const const_iterator &I) const { return I.impl == impl; } - bool operator!=(const const_iterator &I) const { return I.impl != impl; } - const BugReport* operator*() const { return *impl; } - const BugReport* operator->() const { return *impl; } - }; + typedef llvm::ilist::iterator iterator; + typedef llvm::ilist::const_iterator const_iterator; - iterator begin() { return iterator(Reports.begin()); } - iterator end() { return iterator(Reports.end()); } + iterator begin() { return Reports.begin(); } + iterator end() { return Reports.end(); } - const_iterator begin() const { return const_iterator(Reports.begin()); } - const_iterator end() const { return const_iterator(Reports.end()); } + const_iterator begin() const { return Reports.begin(); } + const_iterator end() const { return Reports.end(); } }; //===----------------------------------------------------------------------===// diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp index 8ac785ce7d..c40912ce2f 100644 --- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -24,7 +24,7 @@ #include "clang/AST/ParentMap.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" // The number of CFGBlock pointers we want to reserve memory for. This is used // once for each function we analyze. diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 9186321a5a..bf461b2cf9 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1383,10 +1383,7 @@ PathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const { // Methods for BugReporter and subclasses. //===----------------------------------------------------------------------===// -BugReportEquivClass::~BugReportEquivClass() { - for (iterator I=begin(), E=end(); I!=E; ++I) delete *I; -} - +BugReportEquivClass::~BugReportEquivClass() { } GRBugReporter::~GRBugReporter() { } BugReporterData::~BugReporterData() {} @@ -1809,17 +1806,17 @@ FindReportInEquivalenceClass(BugReportEquivClass& EQ, BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end(); assert(I != E); - BugReport *R = *I; - BugType& BT = R->getBugType(); + 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. if (!BT.isSuppressOnSink()) { + BugReport *R = I; for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) { const ExplodedNode *N = I->getErrorNode(); if (N) { - R = *I; + R = I; bugReports.push_back(R); } } @@ -1835,8 +1832,7 @@ FindReportInEquivalenceClass(BugReportEquivClass& EQ, BugReport *exampleReport = 0; for (; I != E; ++I) { - R = *I; - const ExplodedNode *errorNode = R->getErrorNode(); + const ExplodedNode *errorNode = I->getErrorNode(); if (!errorNode) continue; @@ -1846,9 +1842,9 @@ FindReportInEquivalenceClass(BugReportEquivClass& EQ, } // No successors? By definition this nodes isn't post-dominated by a sink. if (errorNode->succ_empty()) { - bugReports.push_back(R); + bugReports.push_back(I); if (!exampleReport) - exampleReport = R; + exampleReport = I; continue; } @@ -1872,9 +1868,9 @@ FindReportInEquivalenceClass(BugReportEquivClass& EQ, if (Succ->succ_empty()) { // If we found an end-of-path node that is not a sink. if (!Succ->isSink()) { - bugReports.push_back(R); + bugReports.push_back(I); if (!exampleReport) - exampleReport = R; + exampleReport = I; WL.clear(); break; } diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 4789f354e4..35c751a89d 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2026,9 +2026,7 @@ void ExprEngine::ViewGraph(bool trim) { // Iterate through the reports and get their nodes. for (BugReporter::EQClasses_iterator EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { - BugReportEquivClass& EQ = *EI; - const BugReport &R = **EQ.begin(); - ExplodedNode *N = const_cast(R.getErrorNode()); + ExplodedNode *N = const_cast(EI->begin()->getErrorNode()); if (N) Src.push_back(N); } diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 16f5d0bb1a..0440ca953a 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -14,8 +14,9 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" -#include "llvm/Support/SaveAndRestore.h" #include "clang/AST/DeclCXX.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/Support/SaveAndRestore.h" using namespace clang; using namespace ento; -- 2.40.0