[clang-tools-extra] [clang-tidy] Fix readability-else-after-return for if statements appear in unbraced switch case labels (PR #181878)

Berkay Sahin via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 17 10:20:39 PST 2026


https://github.com/berkaysahiin created https://github.com/llvm/llvm-project/pull/181878

- Updates matcher registration in ElseAfterReturnCheck to also handle switchCase(has(ifStmt(...))) patterns
- Adds a regression test for the unbraced switch-case scenario

Fixes #160033

>From 1d3b55827cc47242ab10955db0ebe27c557fdfff Mon Sep 17 00:00:00 2001
From: Berkay <berkaysahindev at gmail.com>
Date: Tue, 17 Feb 2026 21:05:55 +0300
Subject: [PATCH] [clang-tidy] Fix readability-else-after-return for if
 statements appear in unbraced switch case labels

---
 .../readability/ElseAfterReturnCheck.cpp         | 16 ++++++++++------
 clang-tools-extra/docs/ReleaseNotes.rst          |  4 ++++
 .../checkers/readability/else-after-return.cpp   | 16 ++++++++++++++++
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index fccda912947eb..cb3818d93cc81 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -169,14 +169,18 @@ void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
   const auto InterruptsControlFlow = stmt(anyOf(
       returnStmt().bind(InterruptingStr), continueStmt().bind(InterruptingStr),
       breakStmt().bind(InterruptingStr), cxxThrowExpr().bind(InterruptingStr)));
+
+  const auto IfWithInterruptingThenElse =
+      ifStmt(unless(isConstexpr()), unless(isConsteval()),
+             hasThen(stmt(anyOf(InterruptsControlFlow,
+                                compoundStmt(has(InterruptsControlFlow))))),
+             hasElse(stmt().bind("else")))
+          .bind("if");
+
   Finder->addMatcher(
       compoundStmt(
-          forEach(ifStmt(unless(isConstexpr()), unless(isConsteval()),
-                         hasThen(stmt(
-                             anyOf(InterruptsControlFlow,
-                                   compoundStmt(has(InterruptsControlFlow))))),
-                         hasElse(stmt().bind("else")))
-                      .bind("if")))
+          forEach(stmt(anyOf(IfWithInterruptingThenElse,
+                             switchCase(has(IfWithInterruptingThenElse))))))
           .bind("cs"),
       this);
 }
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5c0060877a67f..ce3eee29949d6 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -218,6 +218,10 @@ Changes in existing checks
   <clang-tidy/checks/performance/move-const-arg>` check by avoiding false
   positives on trivially copyable types with a non-public copy constructor.
 
+- Improved :doc:`readability-else-after-return
+  <clang-tidy/checks/readability/else-after-return>` check by fixing missed
+  diagnostics when ``if`` statements appear in unbraced ``switch`` case labels
+
 - Improved :doc:`readability-enum-initial-value
   <clang-tidy/checks/readability/enum-initial-value>` check: the warning message
   now uses separate note diagnostics for each uninitialized enumerator, making
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return.cpp
index 220c7ba19fed0..63ece00dfde5f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return.cpp
@@ -312,3 +312,19 @@ void testPPConditionals() {
   }
 #endif
 }
+
+void testSwitchCaseWithoutInnerCompound(int i, bool b) {
+  switch (i) {
+  case 0:
+    if (b) {
+      return;
+    } else {
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'return'
+      // CHECK-FIXES: {{^}}    }
+      f(0);
+    }
+    break;
+  default:
+    break;
+  }
+}



More information about the cfe-commits mailing list