Skip to content

Commit 05125ba

Browse files
committed
[Clang] enhance loop analysis to handle variable changes inside lambdas
1 parent ed2b82f commit 05125ba

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ Improvements to Clang's diagnostics
319319
- ``-Wc++98-compat`` no longer diagnoses use of ``__auto_type`` or
320320
``decltype(auto)`` as though it was the extension for ``auto``. (#GH47900)
321321

322+
- The ``-Wloop-analysis`` warning now handles variable modifications inside lambda expressions (#GH132038).
323+
322324
Improvements to Clang's time-trace
323325
----------------------------------
324326

clang/lib/Sema/SemaStmt.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,9 +1995,19 @@ namespace {
19951995
}
19961996

19971997
void VisitDeclRefExpr(DeclRefExpr *E) {
1998-
if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
1998+
if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
19991999
if (Decls.count(VD))
20002000
FoundDecl = true;
2001+
} else {
2002+
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getDecl()))
2003+
if (isLambdaCallOperator(MD))
2004+
Visit(MD->getBody());
2005+
}
2006+
}
2007+
2008+
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
2009+
if (Expr *Callee = E->getCallee())
2010+
Visit(Callee);
20012011
}
20022012

20032013
void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
@@ -2014,7 +2024,7 @@ namespace {
20142024

20152025
bool FoundDeclInUse() { return FoundDecl; }
20162026

2017-
}; // end class DeclMatcher
2027+
}; // end class DeclMatcher
20182028

20192029
void CheckForLoopConditionalStatement(Sema &S, Expr *Second,
20202030
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]() { }()) { } // expected-warning {{variables 'a' and 'b' used in loop condition not modified in loop body}}
316+
}

0 commit comments

Comments
 (0)