[clang-tools-extra] [clang-tidy] Fix readability-else-after-return for [[likely]]/[[unlikely]] if (PR #184684)
Berkay Sahin via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 4 13:10:39 PST 2026
https://github.com/berkaysahiin updated https://github.com/llvm/llvm-project/pull/184684
>From 1933ef6ccabc672a17c9877d4464c7efd77c9a26 Mon Sep 17 00:00:00 2001
From: Berkay <berkaysahindev at gmail.com>
Date: Wed, 4 Mar 2026 23:23:51 +0300
Subject: [PATCH] [clang-tidy] Fix readability-else-after-return for
[[likely]]/[[unlikely]] attributed then-branches
---
.../readability/ElseAfterReturnCheck.cpp | 14 +++++++++--
clang-tools-extra/docs/ReleaseNotes.rst | 4 +++-
.../else-after-return-if-likely.cpp | 24 +++++++++++++++++++
3 files changed, 39 insertions(+), 3 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return-if-likely.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index 7e93d619e2a9f..5f0bd27be03cc 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -39,6 +39,15 @@ class PPConditionalCollector : public PPCallbacks {
const SourceManager &SM;
};
+AST_MATCHER_P(Stmt, stripAttribute, ast_matchers::internal::Matcher<Stmt>,
+ InnerMatcher) {
+ const Stmt *S = &Node;
+ if (const auto *AttrStmt = dyn_cast<AttributedStmt>(S))
+ S = AttrStmt->getSubStmt();
+
+ return S && InnerMatcher.matches(*S, Finder, Builder);
+}
+
AST_MATCHER_P(Stmt, stripLabelLikeStatements,
ast_matchers::internal::Matcher<Stmt>, InnerMatcher) {
const Stmt *S = Node.stripLabelLikeStatements();
@@ -178,8 +187,9 @@ void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
const auto IfWithInterruptingThenElse =
ifStmt(unless(isConstexpr()), unless(isConsteval()),
- hasThen(stmt(anyOf(InterruptsControlFlow,
- compoundStmt(has(InterruptsControlFlow))))),
+ hasThen(stripAttribute(
+ stmt(anyOf(InterruptsControlFlow,
+ compoundStmt(has(InterruptsControlFlow)))))),
hasElse(stmt().bind("else")))
.bind("if");
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 309b2df5c2eb4..da7879275efdf 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -282,7 +282,9 @@ Changes in existing checks
- 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.
+ diagnostics when ``if`` statements appear in unbraced ``switch`` case labels,
+ and by handling attributed ``if`` then-branches such as ``[[likely]]`` and
+ ``[[unlikely]]``.
- Improved :doc:`readability-enum-initial-value
<clang-tidy/checks/readability/enum-initial-value>` check: the warning message
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return-if-likely.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return-if-likely.cpp
new file mode 100644
index 0000000000000..9ee450b7b4215
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return-if-likely.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s readability-else-after-return %t -- -- -std=c++20
+
+void f() {
+ if (true) [[likely]] {
+ return;
+ } else { // comment-0
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} } // comment-0
+ }
+
+ if (false) [[unlikely]] {
+ return;
+ } else { // comment-1
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} } // comment-1
+ }
+
+ if (true) [[likely]]
+ return;
+ else // comment-2
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'else' after 'return'
+ // CHECK-FIXES: {{^}} // comment-2
+ int _ = 10;
+}
More information about the cfe-commits
mailing list