https://github.com/juniorrantila updated https://github.com/llvm/llvm-project/pull/222485
>From 2f0bc7ab57aa460a21b2e1d4614b7529b7fc77e2 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 +++++++++++- .../readability/redundant-control-flow.cpp | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) 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/test/clang-tidy/checkers/readability/redundant-control-flow.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-control-flow.cpp index e157e99c5bf0b..0b1755e306a49 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 @@ -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
