[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