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
