summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-06-26 21:12:08 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-06-26 21:12:08 +0000
commit70ec1dd14d66a088be290908d2985652b4863892 (patch)
tree185d994153d2ff060c502ff93cda6275c21dc938 /clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
parentafc2758f5514bac2661868566e0299472796f8b8 (diff)
downloadbcm5719-llvm-70ec1dd14d66a088be290908d2985652b4863892.tar.gz
bcm5719-llvm-70ec1dd14d66a088be290908d2985652b4863892.zip
[analyzer] Do not run visitors until the fixpoint, run only once.
In the current implementation, we run visitors until the fixed point is reached. That is, if a visitor adds another visitor, the currently processed path is destroyed, all diagnostics is discarded, and it is regenerated again, until it's no longer modified. This pattern has a few negative implications: - This loop does not even guarantee to terminate. E.g. just imagine two visitors bouncing a diagnostics around. - Performance-wise, e.g. for sqlite3 all visitors are being re-run at least 10 times for some bugs. We have already seen a few reports where it leads to timeouts. - If we want to add more computationally intense visitors, this will become worse. - From architectural standpoint, the current layout requires copying visitors, which is conceptually wrong, and can be annoying (e.g. no unique_ptr on visitors allowed). The proposed change is a much simpler architecture: the outer loop processes nodes upwards, and whenever the visitor is added it only processes current nodes and above, thus guaranteeing termination. Differential Revision: https://reviews.llvm.org/D47856 llvm-svn: 335666
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp22
1 files changed, 6 insertions, 16 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 589054bdaf6..78e4b8f2508 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1788,8 +1788,7 @@ namespace {
//===---------===//
// Bug Reports. //
//===---------===//
-
- class CFRefReportVisitor : public BugReporterVisitorImpl<CFRefReportVisitor> {
+ class CFRefReportVisitor : public BugReporterVisitor {
protected:
SymbolRef Sym;
const SummaryLogTy &SummaryLog;
@@ -1810,7 +1809,7 @@ namespace {
BugReporterContext &BRC,
BugReport &BR) override;
- std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
+ std::shared_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
BugReport &BR) override;
};
@@ -1821,18 +1820,9 @@ namespace {
const SummaryLogTy &log)
: CFRefReportVisitor(sym, GCEnabled, log) {}
- std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
+ std::shared_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
BugReport &BR) override;
-
- std::unique_ptr<BugReporterVisitor> clone() const override {
- // The curiously-recurring template pattern only works for one level of
- // subclassing. Rather than make a new template base for
- // CFRefReportVisitor, we simply override clone() to do the right thing.
- // This could be trouble someday if BugReporterVisitorImpl is ever
- // used for something else besides a convenient implementation of clone().
- return llvm::make_unique<CFRefLeakReportVisitor>(*this);
- }
};
class CFRefReport : public BugReport {
@@ -2365,14 +2355,14 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
InterestingMethodContext);
}
-std::unique_ptr<PathDiagnosticPiece>
+std::shared_ptr<PathDiagnosticPiece>
CFRefReportVisitor::getEndPath(BugReporterContext &BRC,
const ExplodedNode *EndN, BugReport &BR) {
BR.markInteresting(Sym);
return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR);
}
-std::unique_ptr<PathDiagnosticPiece>
+std::shared_ptr<PathDiagnosticPiece>
CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
const ExplodedNode *EndN, BugReport &BR) {
@@ -2459,7 +2449,7 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
os << " is not referenced later in this execution path and has a retain "
"count of +" << RV->getCount();
- return llvm::make_unique<PathDiagnosticEventPiece>(L, os.str());
+ return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}
void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
OpenPOWER on IntegriCloud