summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-08-10 18:28:04 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-08-10 18:28:04 +0000
commit088adbfa166310bcf69a862bc10fee951ae915b0 (patch)
tree7f587a0e0c7f766bf313d4994774926d07faacc8 /clang/lib/StaticAnalyzer/Core/RegionStore.cpp
parent5bb9d798b486e6f7d100a340544967c7845d48b2 (diff)
downloadbcm5719-llvm-088adbfa166310bcf69a862bc10fee951ae915b0.tar.gz
bcm5719-llvm-088adbfa166310bcf69a862bc10fee951ae915b0.zip
Invalidate static locals when escaping lambdas
Lambdas can affect static locals even without an explicit capture. rdar://39537031 Differential Revision: https://reviews.llvm.org/D50368 llvm-svn: 339459
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index db6449e6d5f..821b7f0edbe 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/TargetInfo.h"
@@ -1033,6 +1034,32 @@ void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
B = B.remove(baseR);
}
+ if (const auto *TO = dyn_cast<TypedValueRegion>(baseR)) {
+ if (const auto *RD = TO->getValueType()->getAsCXXRecordDecl()) {
+
+ // Lambdas can affect all static local variables without explicitly
+ // capturing those.
+ // We invalidate all static locals referenced inside the lambda body.
+ if (RD->isLambda() && RD->getLambdaCallOperator()->getBody()) {
+ using namespace ast_matchers;
+
+ const char *DeclBind = "DeclBind";
+ StatementMatcher RefToStatic = stmt(hasDescendant(declRefExpr(
+ to(varDecl(hasStaticStorageDuration()).bind(DeclBind)))));
+ auto Matches =
+ match(RefToStatic, *RD->getLambdaCallOperator()->getBody(),
+ RD->getASTContext());
+
+ for (BoundNodes &Match : Matches) {
+ auto *VD = Match.getNodeAs<VarDecl>(DeclBind);
+ const VarRegion *ToInvalidate =
+ RM.getRegionManager().getVarRegion(VD, LCtx);
+ AddToWorkList(ToInvalidate);
+ }
+ }
+ }
+ }
+
// BlockDataRegion? If so, invalidate captured variables that are passed
// by reference.
if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
OpenPOWER on IntegriCloud