diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-06-26 21:12:08 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-06-26 21:12:08 +0000 |
commit | 70ec1dd14d66a088be290908d2985652b4863892 (patch) | |
tree | 185d994153d2ff060c502ff93cda6275c21dc938 /clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp | |
parent | afc2758f5514bac2661868566e0299472796f8b8 (diff) | |
download | bcm5719-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/ValistChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp index 039bc08c5c2..bd657340fcf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -69,7 +69,7 @@ private: bool IsCopy) const; void checkVAListEndCall(const CallEvent &Call, CheckerContext &C) const; - class ValistBugVisitor : public BugReporterVisitorImpl<ValistBugVisitor> { + class ValistBugVisitor : public BugReporterVisitor { public: ValistBugVisitor(const MemRegion *Reg, bool IsLeak = false) : Reg(Reg), IsLeak(IsLeak) {} @@ -78,7 +78,7 @@ private: ID.AddPointer(&X); ID.AddPointer(Reg); } - std::unique_ptr<PathDiagnosticPiece> + std::shared_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode, BugReport &BR) override { if (!IsLeak) @@ -87,8 +87,7 @@ private: PathDiagnosticLocation L = PathDiagnosticLocation::createEndOfPath( EndPathNode, BRC.getSourceManager()); // Do not add the statement itself as a range in case of leak. - return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(), - false); + return std::make_shared<PathDiagnosticEventPiece>(L, BR.getDescription(), false); } std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, |