Skip to content

Commit 30a626e

Browse files
committed
[Clang] enhance loop analysis to handle variable changes inside lambdas
1 parent 2206e15 commit 30a626e

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ Improvements to Clang's diagnostics
360360

361361
- An error is now emitted when a ``musttail`` call is made to a function marked with the ``not_tail_called`` attribute. (#GH133509).
362362

363+
- The ``-Wloop-analysis`` warning now handles variable modifications inside lambda expressions (#GH132038).
364+
363365
Improvements to Clang's time-trace
364366
----------------------------------
365367

clang/lib/Sema/SemaStmt.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,9 +2002,23 @@ namespace {
20022002
}
20032003

20042004
void VisitDeclRefExpr(DeclRefExpr *E) {
2005-
if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
2005+
if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
20062006
if (Decls.count(VD))
20072007
FoundDecl = true;
2008+
} else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getDecl());
2009+
MD && isLambdaCallOperator(MD)) {
2010+
for (const auto &Capture : MD->getParent()->captures()) {
2011+
if (VarDecl *VD = dyn_cast<VarDecl>(Capture.getCapturedVar())) {
2012+
if (Decls.count(VD))
2013+
FoundDecl = true;
2014+
}
2015+
}
2016+
}
2017+
}
2018+
2019+
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
2020+
if (Expr *Callee = E->getCallee())
2021+
Visit(E->getCallee());
20082022
}
20092023

20102024
void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
@@ -2021,7 +2035,7 @@ namespace {
20212035

20222036
bool FoundDeclInUse() { return FoundDecl; }
20232037

2024-
}; // end class DeclMatcher
2038+
}; // end class DeclMatcher
20252039

20262040
void CheckForLoopConditionalStatement(Sema &S, Expr *Second,
20272041
Expr *Third, Stmt *Body) {

clang/test/SemaCXX/warn-loop-analysis.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,18 @@ void test10() {
299299
for (auto[i, j, k] = arr; i < a; ++i) { }
300300
for (auto[i, j, k] = arr; i < a; ++arr[0]) { }
301301
};
302+
303+
extern void foo(int);
304+
void test11() {
305+
int a = 0;
306+
auto incr_a = [&a]() { ++a; };
307+
308+
for (int b = 10; a <= b; incr_a())
309+
foo(a);
310+
311+
for (int b = 10; a <= b;)
312+
incr_a();
313+
314+
for (int b = 10; a <= b; [&a]() { ++a; }()) { }
315+
for (int b = 10; a <= b; [&a]() { }()) { }
316+
}

0 commit comments

Comments
 (0)