[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-22 Thread Baranov Victor via cfe-commits

https://github.com/vbvictor closed 
https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-18 Thread via cfe-commits

flovent wrote:

> LGTM. I tried to address the specific case of tuple structured bindings in my 
> PR: #147410. Your PR handles the case for all structured bindings. It may be 
> a good idea to add tests for tuple (you can lift from my PR) and array 
> structured bindings too.

Thanks for the review and advice, these testcases have now been added.

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-18 Thread via cfe-commits

https://github.com/flovent edited 
https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-18 Thread via cfe-commits

https://github.com/flovent updated 
https://github.com/llvm/llvm-project/pull/144213

>From 69d64b55d34b84a316cf4674b304f5535d9aa9d4 Mon Sep 17 00:00:00 2001
From: flovent 
Date: Sat, 14 Jun 2025 15:52:26 +0800
Subject: [PATCH 1/5] [clang-tidy] Improve `bugprone-infinite-loop` check by
 adding handing for strucuted bindings

---
 .../clang-tidy/bugprone/InfiniteLoopCheck.cpp | 33 +++-
 .../clang-tidy/utils/Aliasing.cpp | 14 ++--
 clang-tools-extra/clang-tidy/utils/Aliasing.h |  2 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checkers/bugprone/infinite-loop.cpp   | 81 +++
 5 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 3c3024d538785..951d67ab5c21a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -49,7 +49,7 @@ static Matcher loopEndingStmt(Matcher Internal) {
 }
 
 /// Return whether `Var` was changed in `LoopStmt`.
-static bool isChanged(const Stmt *LoopStmt, const VarDecl *Var,
+static bool isChanged(const Stmt *LoopStmt, const ValueDecl *Var,
   ASTContext *Context) {
   if (const auto *ForLoop = dyn_cast(LoopStmt))
 return (ForLoop->getInc() &&
@@ -82,6 +82,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{
+if (!DD->isLocalVarDeclOrParm())
+  return true;
+
+if (DD->getType().isVolatileQualified())
+  return true;
+
+if (!BD->getType().getTypePtr()->isIntegerType())
+  return true;
+
+return hasPtrOrReferenceInFunc(Func, BD) ||
+   isChanged(LoopStmt, BD, Context);
+  }
+}
   } else if (isa(Cond)) {
 // FIXME: Handle MemberExpr.
@@ -123,6 +140,10 @@ static std::string getCondVarNames(const Stmt *Cond) {
   if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *Var = dyn_cast(DRE->getDecl()))
   return std::string(Var->getName());
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  return std::string(BD->getName());
+}
   }
 
   std::string Result;
@@ -214,10 +235,18 @@ static bool overlap(ArrayRef SCC,
 
 /// returns true iff `Cond` involves at least one static local variable.
 static bool hasStaticLocalVariable(const Stmt *Cond) {
-  if (const auto *DRE = dyn_cast(Cond))
+  if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *VD = dyn_cast(DRE->getDecl()))
   if (VD->isStaticLocal())
 return true;
+
+if (const auto *BD = dyn_cast(DRE->getDecl()))
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl()))
+if (DD->isStaticLocal())
+  return true;
+  }
+
   for (const Stmt *Child : Cond->children())
 if (Child && hasStaticLocalVariable(Child))
   return true;
diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp 
b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
index 2facf0625605e..cbe4873b5c022 100644
--- a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
+++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
@@ -14,14 +14,14 @@
 namespace clang::tidy::utils {
 
 /// Return whether \p S is a reference to the declaration of \p Var.
-static bool isAccessForVar(const Stmt *S, const VarDecl *Var) {
+static bool isAccessForVar(const Stmt *S, const ValueDecl *Var) {
   if (const auto *DRE = dyn_cast(S))
 return DRE->getDecl() == Var;
 
   return false;
 }
 
-static bool capturesByRef(const CXXRecordDecl *RD, const VarDecl *Var) {
+static bool capturesByRef(const CXXRecordDecl *RD, const ValueDecl *Var) {
   return llvm::any_of(RD->captures(), [Var](const LambdaCapture &C) {
 return C.capturesVariable() && C.getCaptureKind() == LCK_ByRef &&
C.getCapturedVar() == Var;
@@ -29,9 +29,9 @@ static bool capturesByRef(const CXXRecordDecl *RD, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) {
+static bool isPtrOrReferenceForVar(const Stmt *S, const ValueDecl *Var) {
   // Treat block capture by reference as a form of taking a reference.
-  if (Var->isEscapingByref())
+  if (const auto *VD = dyn_cast(Var); VD && VD->isEscapingByref())
 return true;
 
   if (const auto *DS = dyn_cast(S)) {
@@ -61,7 +61,7 @@ static bool isPtrOrReferenceForVar(const Stmt *S, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) {
+static bool hasPtrOrReferenceInStmt(const Stmt *S, const ValueDecl *Var) {
   if (isPtrOrReferenceFor

[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-17 Thread via cfe-commits


@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast(BD->getDecomposedDecl())) {
+if (!DD->isLocalVarDeclOrParm())
+  return true;
+
+if (DD->getType().isVolatileQualified())
+  return true;
+
+if (!BD->getType().getTypePtr()->isIntegerType())
+  return true;
+
+return hasPtrOrReferenceInFunc(Func, BD) ||
+   isChanged(LoopStmt, BD, Context);

flovent wrote:

Done in 
[87a68f7](https://github.com/llvm/llvm-project/pull/144213/commits/87a68f7ca9144f05eb37a51abc537af2fcb53fb2)

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-17 Thread via cfe-commits

https://github.com/flovent updated 
https://github.com/llvm/llvm-project/pull/144213

>From 6fce04d8484a3600f292a8bbdd8621db25be7f1d Mon Sep 17 00:00:00 2001
From: flovent 
Date: Sat, 14 Jun 2025 15:52:26 +0800
Subject: [PATCH 1/4] [clang-tidy] Improve `bugprone-infinite-loop` check by
 adding handing for strucuted bindings

---
 .../clang-tidy/bugprone/InfiniteLoopCheck.cpp | 33 +++-
 .../clang-tidy/utils/Aliasing.cpp | 14 ++--
 clang-tools-extra/clang-tidy/utils/Aliasing.h |  2 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checkers/bugprone/infinite-loop.cpp   | 81 +++
 5 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 3c3024d538785..951d67ab5c21a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -49,7 +49,7 @@ static Matcher loopEndingStmt(Matcher Internal) {
 }
 
 /// Return whether `Var` was changed in `LoopStmt`.
-static bool isChanged(const Stmt *LoopStmt, const VarDecl *Var,
+static bool isChanged(const Stmt *LoopStmt, const ValueDecl *Var,
   ASTContext *Context) {
   if (const auto *ForLoop = dyn_cast(LoopStmt))
 return (ForLoop->getInc() &&
@@ -82,6 +82,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{
+if (!DD->isLocalVarDeclOrParm())
+  return true;
+
+if (DD->getType().isVolatileQualified())
+  return true;
+
+if (!BD->getType().getTypePtr()->isIntegerType())
+  return true;
+
+return hasPtrOrReferenceInFunc(Func, BD) ||
+   isChanged(LoopStmt, BD, Context);
+  }
+}
   } else if (isa(Cond)) {
 // FIXME: Handle MemberExpr.
@@ -123,6 +140,10 @@ static std::string getCondVarNames(const Stmt *Cond) {
   if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *Var = dyn_cast(DRE->getDecl()))
   return std::string(Var->getName());
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  return std::string(BD->getName());
+}
   }
 
   std::string Result;
@@ -214,10 +235,18 @@ static bool overlap(ArrayRef SCC,
 
 /// returns true iff `Cond` involves at least one static local variable.
 static bool hasStaticLocalVariable(const Stmt *Cond) {
-  if (const auto *DRE = dyn_cast(Cond))
+  if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *VD = dyn_cast(DRE->getDecl()))
   if (VD->isStaticLocal())
 return true;
+
+if (const auto *BD = dyn_cast(DRE->getDecl()))
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl()))
+if (DD->isStaticLocal())
+  return true;
+  }
+
   for (const Stmt *Child : Cond->children())
 if (Child && hasStaticLocalVariable(Child))
   return true;
diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp 
b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
index 2facf0625605e..cbe4873b5c022 100644
--- a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
+++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
@@ -14,14 +14,14 @@
 namespace clang::tidy::utils {
 
 /// Return whether \p S is a reference to the declaration of \p Var.
-static bool isAccessForVar(const Stmt *S, const VarDecl *Var) {
+static bool isAccessForVar(const Stmt *S, const ValueDecl *Var) {
   if (const auto *DRE = dyn_cast(S))
 return DRE->getDecl() == Var;
 
   return false;
 }
 
-static bool capturesByRef(const CXXRecordDecl *RD, const VarDecl *Var) {
+static bool capturesByRef(const CXXRecordDecl *RD, const ValueDecl *Var) {
   return llvm::any_of(RD->captures(), [Var](const LambdaCapture &C) {
 return C.capturesVariable() && C.getCaptureKind() == LCK_ByRef &&
C.getCapturedVar() == Var;
@@ -29,9 +29,9 @@ static bool capturesByRef(const CXXRecordDecl *RD, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) {
+static bool isPtrOrReferenceForVar(const Stmt *S, const ValueDecl *Var) {
   // Treat block capture by reference as a form of taking a reference.
-  if (Var->isEscapingByref())
+  if (const auto *VD = dyn_cast(Var); VD && VD->isEscapingByref())
 return true;
 
   if (const auto *DS = dyn_cast(S)) {
@@ -61,7 +61,7 @@ static bool isPtrOrReferenceForVar(const Stmt *S, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) {
+static bool hasPtrOrReferenceInStmt(const Stmt *S, const ValueDecl *Var) {
   if (isPtrOrReferenceFor

[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-17 Thread Carlos Galvez via cfe-commits

https://github.com/carlosgalvezp approved this pull request.

LGTM, but please rebase onto latest trunk and address/resolve pending comments.

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-16 Thread Congcong Cai via cfe-commits


@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast(BD->getDecomposedDecl())) {
+if (!DD->isLocalVarDeclOrParm())
+  return true;
+
+if (DD->getType().isVolatileQualified())
+  return true;
+
+if (!BD->getType().getTypePtr()->isIntegerType())
+  return true;
+
+return hasPtrOrReferenceInFunc(Func, BD) ||
+   isChanged(LoopStmt, BD, Context);

HerrCai0907 wrote:

avoid duplicated code with `VarDecl` part. extract them to separated function

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-16 Thread Congcong Cai via cfe-commits

https://github.com/HerrCai0907 approved this pull request.

LGTM except nit

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-07-16 Thread Congcong Cai via cfe-commits

https://github.com/HerrCai0907 edited 
https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-26 Thread Baranov Victor via cfe-commits

https://github.com/vbvictor approved this pull request.

LGTM, but I'd like to wait for a second reviewer for some time to double-check 
if some tests are missing

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-24 Thread via cfe-commits

https://github.com/flovent updated 
https://github.com/llvm/llvm-project/pull/144213

>From 87e03841749296dbdf3e93cc3655a8a48c793da9 Mon Sep 17 00:00:00 2001
From: flovent 
Date: Sat, 14 Jun 2025 15:52:26 +0800
Subject: [PATCH 1/3] [clang-tidy] Improve `bugprone-infinite-loop` check by
 adding handing for strucuted bindings

---
 .../clang-tidy/bugprone/InfiniteLoopCheck.cpp | 33 +++-
 .../clang-tidy/utils/Aliasing.cpp | 14 ++--
 clang-tools-extra/clang-tidy/utils/Aliasing.h |  2 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checkers/bugprone/infinite-loop.cpp   | 81 +++
 5 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 07116a7ff15f5..4ceca53e2f7f3 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -50,7 +50,7 @@ static Matcher loopEndingStmt(Matcher Internal) {
 }
 
 /// Return whether `Var` was changed in `LoopStmt`.
-static bool isChanged(const Stmt *LoopStmt, const VarDecl *Var,
+static bool isChanged(const Stmt *LoopStmt, const ValueDecl *Var,
   ASTContext *Context) {
   if (const auto *ForLoop = dyn_cast(LoopStmt))
 return (ForLoop->getInc() &&
@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{
+if (!DD->isLocalVarDeclOrParm())
+  return true;
+
+if (DD->getType().isVolatileQualified())
+  return true;
+
+if (!BD->getType().getTypePtr()->isIntegerType())
+  return true;
+
+return hasPtrOrReferenceInFunc(Func, BD) ||
+   isChanged(LoopStmt, BD, Context);
+  }
+}
   } else if (isa(Cond)) {
 // FIXME: Handle MemberExpr.
@@ -124,6 +141,10 @@ static std::string getCondVarNames(const Stmt *Cond) {
   if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *Var = dyn_cast(DRE->getDecl()))
   return std::string(Var->getName());
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  return std::string(BD->getName());
+}
   }
 
   std::string Result;
@@ -215,10 +236,18 @@ static bool overlap(ArrayRef SCC,
 
 /// returns true iff `Cond` involves at least one static local variable.
 static bool hasStaticLocalVariable(const Stmt *Cond) {
-  if (const auto *DRE = dyn_cast(Cond))
+  if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *VD = dyn_cast(DRE->getDecl()))
   if (VD->isStaticLocal())
 return true;
+
+if (const auto *BD = dyn_cast(DRE->getDecl()))
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl()))
+if (DD->isStaticLocal())
+  return true;
+  }
+
   for (const Stmt *Child : Cond->children())
 if (Child && hasStaticLocalVariable(Child))
   return true;
diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp 
b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
index 2facf0625605e..cbe4873b5c022 100644
--- a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
+++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
@@ -14,14 +14,14 @@
 namespace clang::tidy::utils {
 
 /// Return whether \p S is a reference to the declaration of \p Var.
-static bool isAccessForVar(const Stmt *S, const VarDecl *Var) {
+static bool isAccessForVar(const Stmt *S, const ValueDecl *Var) {
   if (const auto *DRE = dyn_cast(S))
 return DRE->getDecl() == Var;
 
   return false;
 }
 
-static bool capturesByRef(const CXXRecordDecl *RD, const VarDecl *Var) {
+static bool capturesByRef(const CXXRecordDecl *RD, const ValueDecl *Var) {
   return llvm::any_of(RD->captures(), [Var](const LambdaCapture &C) {
 return C.capturesVariable() && C.getCaptureKind() == LCK_ByRef &&
C.getCapturedVar() == Var;
@@ -29,9 +29,9 @@ static bool capturesByRef(const CXXRecordDecl *RD, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) {
+static bool isPtrOrReferenceForVar(const Stmt *S, const ValueDecl *Var) {
   // Treat block capture by reference as a form of taking a reference.
-  if (Var->isEscapingByref())
+  if (const auto *VD = dyn_cast(Var); VD && VD->isEscapingByref())
 return true;
 
   if (const auto *DS = dyn_cast(S)) {
@@ -61,7 +61,7 @@ static bool isPtrOrReferenceForVar(const Stmt *S, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) {
+static bool hasPtrOrReferenceInStmt(const Stmt *S, const ValueDecl *Var) {
   if (isPtrOrReferenceFor

[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-23 Thread via cfe-commits

flovent wrote:

ping.

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread via cfe-commits

https://github.com/flovent deleted 
https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread via cfe-commits

flovent wrote:

New CI failure seems unrelated to the new commit.

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread via cfe-commits


@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{

flovent wrote:

But does `BindingDecl::getDecomposedDecl` always return non null value? I find 
the use of this API in clang, `ValueDecl::getPotentiallyDecomposedVarDecl` does 
check it nullability,
```
VarDecl *ValueDecl::getPotentiallyDecomposedVarDecl() {
  // ...
  if (auto *BD = llvm::dyn_cast(this))
return llvm::dyn_cast_if_present(BD->getDecomposedDecl());
  return nullptr;
}
```

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread via cfe-commits


@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{

flovent wrote:

You are right, null check should not be necessary here, updated.

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread via cfe-commits

https://github.com/flovent updated 
https://github.com/llvm/llvm-project/pull/144213

>From 87e03841749296dbdf3e93cc3655a8a48c793da9 Mon Sep 17 00:00:00 2001
From: flovent 
Date: Sat, 14 Jun 2025 15:52:26 +0800
Subject: [PATCH 1/2] [clang-tidy] Improve `bugprone-infinite-loop` check by
 adding handing for strucuted bindings

---
 .../clang-tidy/bugprone/InfiniteLoopCheck.cpp | 33 +++-
 .../clang-tidy/utils/Aliasing.cpp | 14 ++--
 clang-tools-extra/clang-tidy/utils/Aliasing.h |  2 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 +
 .../checkers/bugprone/infinite-loop.cpp   | 81 +++
 5 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 07116a7ff15f5..4ceca53e2f7f3 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -50,7 +50,7 @@ static Matcher loopEndingStmt(Matcher Internal) {
 }
 
 /// Return whether `Var` was changed in `LoopStmt`.
-static bool isChanged(const Stmt *LoopStmt, const VarDecl *Var,
+static bool isChanged(const Stmt *LoopStmt, const ValueDecl *Var,
   ASTContext *Context) {
   if (const auto *ForLoop = dyn_cast(LoopStmt))
 return (ForLoop->getInc() &&
@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{
+if (!DD->isLocalVarDeclOrParm())
+  return true;
+
+if (DD->getType().isVolatileQualified())
+  return true;
+
+if (!BD->getType().getTypePtr()->isIntegerType())
+  return true;
+
+return hasPtrOrReferenceInFunc(Func, BD) ||
+   isChanged(LoopStmt, BD, Context);
+  }
+}
   } else if (isa(Cond)) {
 // FIXME: Handle MemberExpr.
@@ -124,6 +141,10 @@ static std::string getCondVarNames(const Stmt *Cond) {
   if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *Var = dyn_cast(DRE->getDecl()))
   return std::string(Var->getName());
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  return std::string(BD->getName());
+}
   }
 
   std::string Result;
@@ -215,10 +236,18 @@ static bool overlap(ArrayRef SCC,
 
 /// returns true iff `Cond` involves at least one static local variable.
 static bool hasStaticLocalVariable(const Stmt *Cond) {
-  if (const auto *DRE = dyn_cast(Cond))
+  if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *VD = dyn_cast(DRE->getDecl()))
   if (VD->isStaticLocal())
 return true;
+
+if (const auto *BD = dyn_cast(DRE->getDecl()))
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl()))
+if (DD->isStaticLocal())
+  return true;
+  }
+
   for (const Stmt *Child : Cond->children())
 if (Child && hasStaticLocalVariable(Child))
   return true;
diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp 
b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
index 2facf0625605e..cbe4873b5c022 100644
--- a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
+++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp
@@ -14,14 +14,14 @@
 namespace clang::tidy::utils {
 
 /// Return whether \p S is a reference to the declaration of \p Var.
-static bool isAccessForVar(const Stmt *S, const VarDecl *Var) {
+static bool isAccessForVar(const Stmt *S, const ValueDecl *Var) {
   if (const auto *DRE = dyn_cast(S))
 return DRE->getDecl() == Var;
 
   return false;
 }
 
-static bool capturesByRef(const CXXRecordDecl *RD, const VarDecl *Var) {
+static bool capturesByRef(const CXXRecordDecl *RD, const ValueDecl *Var) {
   return llvm::any_of(RD->captures(), [Var](const LambdaCapture &C) {
 return C.capturesVariable() && C.getCaptureKind() == LCK_ByRef &&
C.getCapturedVar() == Var;
@@ -29,9 +29,9 @@ static bool capturesByRef(const CXXRecordDecl *RD, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) {
+static bool isPtrOrReferenceForVar(const Stmt *S, const ValueDecl *Var) {
   // Treat block capture by reference as a form of taking a reference.
-  if (Var->isEscapingByref())
+  if (const auto *VD = dyn_cast(Var); VD && VD->isEscapingByref())
 return true;
 
   if (const auto *DS = dyn_cast(S)) {
@@ -61,7 +61,7 @@ static bool isPtrOrReferenceForVar(const Stmt *S, const 
VarDecl *Var) {
 }
 
 /// Return whether \p Var has a pointer or reference in \p S.
-static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) {
+static bool hasPtrOrReferenceInStmt(const Stmt *S, const ValueDecl *Var) {
   if (isPtrOrReferenceFor

[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread Baranov Victor via cfe-commits


@@ -215,10 +236,18 @@ static bool overlap(ArrayRef SCC,
 
 /// returns true iff `Cond` involves at least one static local variable.
 static bool hasStaticLocalVariable(const Stmt *Cond) {
-  if (const auto *DRE = dyn_cast(Cond))
+  if (const auto *DRE = dyn_cast(Cond)) {
 if (const auto *VD = dyn_cast(DRE->getDecl()))
   if (VD->isStaticLocal())
 return true;
+
+if (const auto *BD = dyn_cast(DRE->getDecl()))
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl()))

vbvictor wrote:

same with `dyn_cast_if_present` here

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread Baranov Victor via cfe-commits


@@ -83,6 +83,23 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, 
const Stmt *LoopStmt,
  isChanged(LoopStmt, Var, Context);
   // FIXME: Track references.
 }
+
+if (const auto *BD = dyn_cast(DRE->getDecl())) {
+  if (const auto *DD =
+  dyn_cast_if_present(BD->getDecomposedDecl())) 
{

vbvictor wrote:

What is the profit of using `dyn_cast_if_present` here?
`DecompositionDecl` may or may not be there, but the same rules apply to 
previous cast: `BindingDecl` also may or not be there. 

https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve `bugprone-infinite-loop` check by adding handing for structured bindings (PR #144213)

2025-06-14 Thread via cfe-commits

https://github.com/flovent edited 
https://github.com/llvm/llvm-project/pull/144213
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits