[clang] [Clang] enhance loop analysis to handle variable changes inside lambdas (PR #135573)
Oleksandr T. via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 15 15:09:10 PDT 2025
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/135573
>From ab01bebfa99f635d80c234e19bf3aa73977ce149 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 16 Apr 2025 01:08:55 +0300
Subject: [PATCH] [Clang] enhance loop analysis to handle variable changes
inside lambdas
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaStmt.cpp | 21 +++++++++++++++++++--
clang/test/SemaCXX/warn-loop-analysis.cpp | 15 +++++++++++++++
3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 166f26921cb71..3e83041a9cd9c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -371,6 +371,8 @@ Improvements to Clang's diagnostics
- An error is now emitted when a ``musttail`` call is made to a function marked with the ``not_tail_called`` attribute. (#GH133509).
+- The ``-Wloop-analysis`` warning now handles variable modifications inside lambda expressions (#GH132038).
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 39c2e157591df..38bc6687ecb60 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2002,9 +2002,26 @@ namespace {
}
void VisitDeclRefExpr(DeclRefExpr *E) {
- if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
+ if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
if (Decls.count(VD))
FoundDecl = true;
+ } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getDecl());
+ MD && isLambdaCallOperator(MD)) {
+ for (const auto &Capture : MD->getParent()->captures()) {
+ if (!Capture.capturesVariable())
+ continue;
+
+ if (VarDecl *VD = dyn_cast<VarDecl>(Capture.getCapturedVar())) {
+ if (Decls.count(VD))
+ FoundDecl = true;
+ }
+ }
+ }
+ }
+
+ void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ if (Expr *Callee = E->getCallee())
+ Visit(E->getCallee());
}
void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
@@ -2021,7 +2038,7 @@ namespace {
bool FoundDeclInUse() { return FoundDecl; }
- }; // end class DeclMatcher
+ }; // end class DeclMatcher
void CheckForLoopConditionalStatement(Sema &S, Expr *Second,
Expr *Third, Stmt *Body) {
diff --git a/clang/test/SemaCXX/warn-loop-analysis.cpp b/clang/test/SemaCXX/warn-loop-analysis.cpp
index 324dd386292ac..4f7c70f65677b 100644
--- a/clang/test/SemaCXX/warn-loop-analysis.cpp
+++ b/clang/test/SemaCXX/warn-loop-analysis.cpp
@@ -299,3 +299,18 @@ void test10() {
for (auto[i, j, k] = arr; i < a; ++i) { }
for (auto[i, j, k] = arr; i < a; ++arr[0]) { }
};
+
+extern void foo(int);
+void test11() {
+ int a = 0;
+ auto incr_a = [&a]() { ++a; };
+
+ for (int b = 10; a <= b; incr_a())
+ foo(a);
+
+ for (int b = 10; a <= b;)
+ incr_a();
+
+ for (int b = 10; a <= b; [&a]() { ++a; }()) { }
+ for (int b = 10; a <= b; [&a]() { }()) { }
+}
More information about the cfe-commits
mailing list