Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ 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 @@ B = B.remove(baseR); } + if (const auto *TO = dyn_cast(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(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(baseR)) { Index: clang/test/Analysis/lambdas.cpp =================================================================== --- clang/test/Analysis/lambdas.cpp +++ clang/test/Analysis/lambdas.cpp @@ -348,6 +348,18 @@ lambda(); } +void escape(void*); + +int& invalidate_static_on_unknown_lambda() { + static int* z; + auto lambda = [] { + static float zz; + z = new int(120); + }; + escape(&lambda); + return *z; // no-warning +} + static int b = 0;