https://github.com/juniorrantila updated 
https://github.com/llvm/llvm-project/pull/222485

>From 10994ec18efb3ec18086591c7f4512a8a7faef67 Mon Sep 17 00:00:00 2001
From: Junior Rantila <[email protected]>
Date: Thu, 10 Sep 2026 02:05:52 +0200
Subject: [PATCH] [clang-tidy] Do not diagnose continue of outer loop

This patch ensures that "readability-redundant-control-flow"
does not trigger a diagnostic when continuing an outer loop
at the end of an inner loop.

```
int robin = 0;
next_client: for (;;) {
  int client = accept(sock);

  for (int i = 0; i < worker_count; i++) {
    robin = (robin + 1) % worker_count;
    Worker* worker = &workers[robin];
    if (worker->is_full())
      continue;
    worker->push(client);
    continue next_client; // This would previously emit diagnostic.
  }

  handle_request(client);
}

```
---
 .../readability/RedundantControlFlowCheck.cpp | 12 ++++++++++-
 clang-tools-extra/docs/ReleaseNotes.md        |  5 +++++
 .../readability/redundant-control-flow.cpp    | 21 ++++++++++++++++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
index 46cbaa1f70301..48d99db2ee79a 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
@@ -39,7 +39,8 @@ void RedundantControlFlowCheck::registerMatchers(MatchFinder 
*Finder) {
       this);
   Finder->addMatcher(mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt)
                          .with(hasBody(compoundStmt(
-                             hasFinalStmt(continueStmt().bind("stmt"))))),
+                             hasFinalStmt(continueStmt().bind("stmt")))))
+                         .bind("loop"),
                      this);
 }
 
@@ -50,6 +51,15 @@ void RedundantControlFlowCheck::check(const 
MatchFinder::MatchResult &Result) {
   if (StmtRange.getBegin().isMacroID())
     return;
 
+  if (const auto *Continue = dyn_cast<ContinueStmt>(&RedundantStmt)) {
+    if (const auto *Label = Continue->getLabelDecl()) {
+      const auto *Loop = Result.Nodes.getNodeAs<Stmt>("loop");
+      const auto *ContinueLoop = Label->getStmt()->getSubStmt();
+      if (Loop != ContinueLoop)
+        return;
+    }
+  }
+
   const auto RemovedRange = CharSourceRange::getCharRange(
       StmtRange.getBegin(),
       Lexer::findLocationAfterToken(StmtRange.getEnd(), tok::semi,
diff --git a/clang-tools-extra/docs/ReleaseNotes.md 
b/clang-tools-extra/docs/ReleaseNotes.md
index a883363fd0775..c8b6a60f82d42 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -252,6 +252,11 @@ infrastructure are described first, followed by 
tool-specific sections.
   exclusively for overload resolution. Added the {option}`IgnoredTypes`
   option to allow customizing the set of ignored types.
 
+- Improved {doc}`readability-redundant-control-flow
+  <clang-tidy/checks/readability/redundant-control-flow>` check by fixing
+  false positive when continuing a labeled outer loop from the end of an
+  inner loop.
+
 - Improved {doc}`readability-trailing-comma
   <clang-tidy/checks/readability/trailing-comma>` check:
 
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-control-flow.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-control-flow.cpp
index e157e99c5bf0b..7ed12c42f8141 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-control-flow.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-control-flow.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-redundant-control-flow %t
+// RUN: %check_clang_tidy %s readability-redundant-control-flow %t -- -- 
-Xclang=-fnamed-loops
 
 void g(int i);
 void j();
@@ -272,3 +272,22 @@ void semicolon_far_from_continue() {
 // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: redundant continue statement at 
the end of loop statement
 // CHECK-FIXES:      for (int i = 0; i < 20; ++i) {
 // CHECK-FIXES-NEXT: }
+
+void continue_labeled_loop() {
+  loop:
+  for (int i = 0; i < 10; ++i) {
+    continue loop;
+  }
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: redundant continue statement at 
the end of loop statement
+// CHECK-FIXES:      for (int i = 0; i < 10; ++i) {
+// CHECK-FIXES-NEXT: }
+
+void continue_outer_labeled_loop() {
+  outer:
+  for (int i = 0; i < 10; ++i) {
+    for (int j = 0; j < 10; ++j) {
+      continue outer;
+    }
+  }
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to