https://github.com/berkaysahiin updated 
https://github.com/llvm/llvm-project/pull/185202

>From 9fd4db3e3ca72eccca786f26e58e4b67d5f0ecdc Mon Sep 17 00:00:00 2001
From: Berkay <[email protected]>
Date: Sat, 7 Mar 2026 19:37:50 +0300
Subject: [PATCH 1/5] [clang-tidy] extend readability-else-after-return to
 remove else after calls to [[noreturn]] functions

---
 .../readability/ElseAfterReturnCheck.cpp      | 22 ++++++++++++++++++-
 clang-tools-extra/docs/ReleaseNotes.rst       |  9 ++++++--
 .../readability/else-after-return.cpp         | 12 ++++++++++
 3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index 7e93d619e2a9f..4160f0fcf1dc1 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -39,6 +39,23 @@ class PPConditionalCollector : public PPCallbacks {
   const SourceManager &SM;
 };
 
+bool isNoReturnStmt(const Stmt &Stmt) {
+  const auto *Call = dyn_cast<CallExpr>(&Stmt);
+  if (!Call)
+    return false;
+
+  const FunctionDecl *Func = Call->getDirectCallee();
+  if (!Func)
+    return false;
+
+  return Func->isNoReturn();
+}
+
+AST_MATCHER(Stmt, isNoReturnStmt) {
+  const Stmt &S = Node;
+  return isNoReturnStmt(S);
+}
+
 AST_MATCHER_P(Stmt, stripLabelLikeStatements,
               ast_matchers::internal::Matcher<Stmt>, InnerMatcher) {
   const Stmt *S = Node.stripLabelLikeStatements();
@@ -174,7 +191,8 @@ void ElseAfterReturnCheck::registerPPCallbacks(const 
SourceManager &SM,
 void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
   const auto InterruptsControlFlow = stmt(anyOf(
       returnStmt().bind(InterruptingStr), continueStmt().bind(InterruptingStr),
-      breakStmt().bind(InterruptingStr), 
cxxThrowExpr().bind(InterruptingStr)));
+      breakStmt().bind(InterruptingStr), cxxThrowExpr().bind(InterruptingStr),
+      stmt(isNoReturnStmt()).bind(InterruptingStr)));
 
   const auto IfWithInterruptingThenElse =
       ifStmt(unless(isConstexpr()), unless(isConsteval()),
@@ -237,6 +255,8 @@ static StringRef getControlFlowString(const Stmt &Stmt) {
     return "break";
   if (isa<CXXThrowExpr>(Stmt))
     return "throw";
+  if (isNoReturnStmt(Stmt))
+    return "noreturn";
   llvm_unreachable("Unknown control flow interrupter");
 }
 
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index b0b4cd646c3bd..33437d2004079 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -295,8 +295,13 @@ Changes in existing checks
   when a member expression has a non-identifier name.
 
 - 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.
+  <clang-tidy/checks/readability/else-after-return>` check:
+
+  - Fixed missed diagnostics when ``if`` statements appear in unbraced
+    ``switch`` case labels.
+
+  - Diagnose and remove redundant ``else`` branches after calls to
+    ``[[noreturn]]`` functions.
 
 - 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.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/readability/else-after-return.cpp
index e987687a764cd..f0788dbf3221b 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
@@ -438,3 +438,15 @@ void testLabels(bool b) {
       f(0);
   }
 }
+
+[[noreturn]] void noReturn();
+
+void testNoReturn() {
+  if (true) {
+    noReturn();
+  } else { // comment-28
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 
'noreturn'
+    // CHECK-FIXES: {{^}}  } // comment-28
+    f(0);
+  }
+}

>From 68d5017a4f90bd14c555b6d47684427dfcd0f73a Mon Sep 17 00:00:00 2001
From: Berkay <[email protected]>
Date: Sat, 7 Mar 2026 20:14:02 +0300
Subject: [PATCH 2/5] [clang-tidy] supress the linter

---
 .../clang-tidy/readability/ElseAfterReturnCheck.cpp             | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index 4160f0fcf1dc1..d4cb863eb9645 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -39,7 +39,7 @@ class PPConditionalCollector : public PPCallbacks {
   const SourceManager &SM;
 };
 
-bool isNoReturnStmt(const Stmt &Stmt) {
+bool isNoReturnStmt(const Stmt &Stmt) { // NOLINT
   const auto *Call = dyn_cast<CallExpr>(&Stmt);
   if (!Call)
     return false;

>From 512f99ee87536c9faaea5e0238c4d1a64c75dcff Mon Sep 17 00:00:00 2001
From: Berkay <[email protected]>
Date: Tue, 10 Mar 2026 01:12:44 +0300
Subject: [PATCH 3/5] Removes custom matcher & Updates warning messages

---
 .../readability/ElseAfterReturnCheck.cpp      | 43 ++++++++-----------
 .../readability/else-after-return.cpp         | 15 ++++++-
 2 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index d4cb863eb9645..4e62236a80920 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -39,23 +39,6 @@ class PPConditionalCollector : public PPCallbacks {
   const SourceManager &SM;
 };
 
-bool isNoReturnStmt(const Stmt &Stmt) { // NOLINT
-  const auto *Call = dyn_cast<CallExpr>(&Stmt);
-  if (!Call)
-    return false;
-
-  const FunctionDecl *Func = Call->getDirectCallee();
-  if (!Func)
-    return false;
-
-  return Func->isNoReturn();
-}
-
-AST_MATCHER(Stmt, isNoReturnStmt) {
-  const Stmt &S = Node;
-  return isNoReturnStmt(S);
-}
-
 AST_MATCHER_P(Stmt, stripLabelLikeStatements,
               ast_matchers::internal::Matcher<Stmt>, InnerMatcher) {
   const Stmt *S = Node.stripLabelLikeStatements();
@@ -65,7 +48,7 @@ AST_MATCHER_P(Stmt, stripLabelLikeStatements,
 } // namespace
 
 static constexpr char InterruptingStr[] = "interrupting";
-static constexpr char WarningMessage[] = "do not use 'else' after '%0'";
+static constexpr char WarningMessage[] = "do not use 'else' after %0";
 static constexpr char WarnOnUnfixableStr[] = "WarnOnUnfixable";
 static constexpr char WarnOnConditionVariablesStr[] =
     "WarnOnConditionVariables";
@@ -134,6 +117,18 @@ static bool containsDeclInScope(const Stmt *Node) {
   return false;
 }
 
+static bool isNoReturnStmt(const Stmt &Stmt) {
+  const auto *Call = dyn_cast<CallExpr>(&Stmt);
+  if (!Call)
+    return false;
+
+  const FunctionDecl *Func = Call->getDirectCallee();
+  if (!Func)
+    return false;
+
+  return Func->isNoReturn();
+}
+
 static void removeElseAndBrackets(DiagnosticBuilder &Diag, ASTContext &Context,
                                   const Stmt *Else, SourceLocation ElseLoc) {
   auto Remap = [&](SourceLocation Loc) {
@@ -192,7 +187,7 @@ void ElseAfterReturnCheck::registerMatchers(MatchFinder 
*Finder) {
   const auto InterruptsControlFlow = stmt(anyOf(
       returnStmt().bind(InterruptingStr), continueStmt().bind(InterruptingStr),
       breakStmt().bind(InterruptingStr), cxxThrowExpr().bind(InterruptingStr),
-      stmt(isNoReturnStmt()).bind(InterruptingStr)));
+      callExpr(callee(functionDecl(isNoReturn()))).bind(InterruptingStr)));
 
   const auto IfWithInterruptingThenElse =
       ifStmt(unless(isConstexpr()), unless(isConsteval()),
@@ -248,15 +243,15 @@ static bool hasPreprocessorBranchEndBetweenLocations(
 
 static StringRef getControlFlowString(const Stmt &Stmt) {
   if (isa<ReturnStmt>(Stmt))
-    return "return";
+    return "'return'";
   if (isa<ContinueStmt>(Stmt))
-    return "continue";
+    return "'continue'";
   if (isa<BreakStmt>(Stmt))
-    return "break";
+    return "'break'";
   if (isa<CXXThrowExpr>(Stmt))
-    return "throw";
+    return "'throw'";
   if (isNoReturnStmt(Stmt))
-    return "noreturn";
+    return "calling a function that doesn't return";
   llvm_unreachable("Unknown control flow interrupter");
 }
 
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 f0788dbf3221b..1f1ac2151234f 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
@@ -441,12 +441,25 @@ void testLabels(bool b) {
 
 [[noreturn]] void noReturn();
 
+struct NoReturnMember {
+  [[noreturn]] void noReturn();
+};
+
 void testNoReturn() {
   if (true) {
     noReturn();
   } else { // comment-28
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 
'noreturn'
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 
calling a function that doesn't return
     // CHECK-FIXES: {{^}}  } // comment-28
     f(0);
   }
+
+  if (true) {
+    NoReturnMember f;
+    f.noReturn();
+  } else { // comment-29
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 
calling a function that doesn't return
+    // CHECK-FIXES: {{^}}  } // comment-29
+    f(0);
+  }
 }

>From 76dc2ce7c0e0ff6df3d918a9dcf7e057ff8bb754 Mon Sep 17 00:00:00 2001
From: Berkay <[email protected]>
Date: Thu, 12 Mar 2026 19:51:49 +0300
Subject: [PATCH 4/5] Removes unused function && Remove whitespaces

---
 .../readability/ElseAfterReturnCheck.cpp          | 15 ++-------------
 clang-tools-extra/docs/ReleaseNotes.rst           |  2 +-
 2 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index baf55797f5d78..91ef0024fe9b9 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "ElseAfterReturnCheck.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
@@ -117,18 +118,6 @@ static bool containsDeclInScope(const Stmt *Node) {
   return false;
 }
 
-static bool isNoReturnStmt(const Stmt &Stmt) {
-  const auto *Call = dyn_cast<CallExpr>(&Stmt);
-  if (!Call)
-    return false;
-
-  const FunctionDecl *Func = Call->getDirectCallee();
-  if (!Func)
-    return false;
-
-  return Func->isNoReturn();
-}
-
 static void removeElseAndBrackets(DiagnosticBuilder &Diag, ASTContext &Context,
                                   const Stmt *Else, SourceLocation ElseLoc) {
   auto Remap = [&](SourceLocation Loc) {
@@ -251,7 +240,7 @@ static StringRef getControlFlowString(const Stmt &Stmt) {
     return "'break'";
   if (isa<CXXThrowExpr>(Stmt))
     return "'throw'";
-  if (isNoReturnStmt(Stmt))
+  if (isa<CallExpr>(Stmt))
     return "calling a function that doesn't return";
   llvm_unreachable("Unknown control flow interrupter");
 }
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 18130d2f207eb..ff8d8867cecb2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -309,7 +309,7 @@ Changes in existing checks
 
   - Fixed missed diagnostics when ``if`` statements appear in unbraced
     ``switch`` case labels.
-    
+ 
   - Added support for handling attributed ``if`` then-branches such as
     ``[[likely]]`` and ``[[unlikely]]``.
 

>From 197914cf24212cac9608819afe5c6ec4c16ddaaf Mon Sep 17 00:00:00 2001
From: Berkay <[email protected]>
Date: Thu, 12 Mar 2026 19:54:50 +0300
Subject: [PATCH 5/5] Removes auto included header

---
 .../clang-tidy/readability/ElseAfterReturnCheck.cpp             | 1 -
 clang-tools-extra/docs/ReleaseNotes.rst                         | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
index 91ef0024fe9b9..73daf53389ec4 100644
--- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -8,7 +8,6 @@
 
 #include "ElseAfterReturnCheck.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index ff8d8867cecb2..1fbdb5e66c3a4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -309,7 +309,7 @@ Changes in existing checks
 
   - Fixed missed diagnostics when ``if`` statements appear in unbraced
     ``switch`` case labels.
- 
+
   - Added support for handling attributed ``if`` then-branches such as
     ``[[likely]]`` and ``[[unlikely]]``.
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to