Skip to content

Conversation

@localspook
Copy link
Contributor

Closes #171200.

@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2025

@llvm/pr-subscribers-clang-tidy

@llvm/pr-subscribers-clang-tools-extra

Author: Victor Chernyakin (localspook)

Changes

Closes #171200.


Full diff: https://github.com/llvm/llvm-project/pull/171287.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp (+5-13)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+5)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/readability/redundant-control-flow.cpp (+30)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
index 132b7ddc4311b..b77108c49f53c 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
@@ -71,19 +71,11 @@ void RedundantControlFlowCheck::issueDiagnostic(
   if (isLocationInMacroExpansion(SM, StmtRange.getBegin()))
     return;
 
-  const CompoundStmt::const_reverse_body_iterator Previous =
-      ++Block->body_rbegin();
-  SourceLocation Start;
-  if (Previous != Block->body_rend())
-    Start = Lexer::findLocationAfterToken(
-        cast<Stmt>(*Previous)->getEndLoc(), tok::semi, SM, getLangOpts(),
-        /*SkipTrailingWhitespaceAndNewLine=*/true);
-  if (!Start.isValid())
-    Start = StmtRange.getBegin();
-  auto RemovedRange = CharSourceRange::getCharRange(
-      Start, Lexer::findLocationAfterToken(
-                 StmtRange.getEnd(), tok::semi, SM, getLangOpts(),
-                 /*SkipTrailingWhitespaceAndNewLine=*/true));
+  const auto RemovedRange = CharSourceRange::getCharRange(
+      StmtRange.getBegin(),
+      Lexer::findLocationAfterToken(StmtRange.getEnd(), tok::semi, SM,
+                                    getLangOpts(),
+                                    /*SkipTrailingWhitespaceAndNewLine=*/true));
 
   diag(StmtRange.getBegin(), Diag) << FixItHint::CreateRemoval(RemovedRange);
 }
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index d1fb1cba3e45a..9f72f31b3cfa9 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -581,6 +581,11 @@ Changes in existing checks
   <clang-tidy/checks/readability/redundant-casting>` check by fixing false
   negatives when explicitly cast from function pointer.
 
+- Improved :doc:`readability-redundant-control-flow
+  <clang-tidy/checks/readability/redundant-control-flow>` by fixing an issue
+  where the check would sometimes suggest deleting not only a redundant
+  ``return`` or ``continue``, but also unrelated lines preceding it.
+
 - Improved :doc:`readability-uppercase-literal-suffix
   <clang-tidy/checks/readability/uppercase-literal-suffix>` check to recognize
   literal suffixes added in C++23 and C23.
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 77644902e7772..0083b5e921bc9 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
@@ -222,3 +222,33 @@ void call_templates() {
   template_loop(10L);
   template_loop(10U);
 }
+
+void dont_delete_lines_before_return_statement() {
+	do {} while (0);
+#ifdef FOO
+#endif
+  return;
+}
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant return statement
+// CHECK-FIXES:      void dont_delete_lines_before_return_statement() {
+// CHECK-FIXES-NEXT: 	 do {} while (0);
+// CHECK-FIXES-NEXT: #ifdef FOO
+// CHECK-FIXES-NEXT: #endif
+// CHECK-FIXES-NEXT: }
+
+void dont_delete_lines_before_continue_statement() {
+  for (;;) {
+	  do {} while (0);
+#ifdef BAR
+#endif
+    continue;
+  }
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant continue statement
+// CHECK-FIXES:      void dont_delete_lines_before_continue_statement() {
+// CHECK-FIXES-NEXT:   for (;;) {
+// CHECK-FIXES-NEXT: 	   do {} while (0);
+// CHECK-FIXES-NEXT: #ifdef BAR
+// CHECK-FIXES-NEXT: #endif
+// CHECK-FIXES-NEXT:   }
+// CHECK-FIXES-NEXT: }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clang-tidy readability-redundant-control-flow removes comments and conditional compilation blocks before the return statement

5 participants