summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/ValistChecker.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/ValistChecker.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/ValistChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp7
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,
OpenPOWER on IntegriCloud