[llvm-branch-commits] [clang] [clang][Sema] Allow musttail calls to [[noreturn]] functions (PR #234605)

Paweł Bylica via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Oct 22 05:47:02 PDT 2026


https://github.com/chfast created https://github.com/llvm/llvm-project/pull/234605

#77727 rejected `[[clang::musttail]]` calls to `[[noreturn]]` functions to avoid a crash in CodeGen. The check covered only `[[noreturn]]`, not `__attribute__((noreturn))`, `_Noreturn` or noreturn function types. CodeGen now handles all of them (#234580), so the error is not needed.

This matches GCC: https://godbolt.org/z/q8ajhMh15

>From 943b9d4ac1f1aa24323f1e5b34120fdedf10665a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Bylica?= <pawel at hepcolgum.band>
Date: Thu, 22 Oct 2026 13:24:35 +0200
Subject: [PATCH] [clang][Sema] Allow musttail calls to [[noreturn]] functions

#77727 rejected `[[clang::musttail]]` calls to `[[noreturn]]` functions
to avoid a crash in CodeGen. The check covered only `[[noreturn]]`, not
`__attribute__((noreturn))`, `_Noreturn` or noreturn function types.
CodeGen now handles all of them (#234580), so the error is not needed.

This matches GCC: https://godbolt.org/z/q8ajhMh15
---
 clang/docs/ReleaseNotes.md                       | 3 +++
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 --
 clang/lib/Sema/SemaStmt.cpp                      | 6 ------
 clang/test/CodeGen/musttail-noreturn.c           | 6 ++++++
 clang/test/SemaCXX/PR76631.cpp                   | 2 +-
 5 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 61bb291008439d..4723296e0a548e 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -456,6 +456,9 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and
   `void (*unlock)(struct BDev *bdev) UNLOCK_FUNCTION(bdev->lock)`, keeps
   working. Without the flag both forward references remain errors.
 
+- `[[clang::musttail]]` calls to `[[noreturn]]` functions are no longer
+  rejected, matching GCC and other ways of declaring a function noreturn.
+
 ### Improvements to Clang's diagnostics
 
 - Fixed spurious `-Wimplicit-void-ptr-cast` warnings in C for parenthesized
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f0e06e314e3c29..ef642ae7462ac2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3391,8 +3391,6 @@ def err_musttail_scope : Error<
   "cannot perform a tail call from this return statement">;
 def err_musttail_no_variadic : Error<
   "%0 attribute may not be used with variadic functions">;
-def err_musttail_no_return : Error<
-  "%0 attribute may not be used with no-return-attribute functions">;
 
 def err_nsobject_attribute : Error<
   "'NSObject' attribute is for pointer types only">;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 4bf5b3f3ec6b74..d17396604daf6c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -908,12 +908,6 @@ bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
     return false;
   }
 
-  const auto *CalleeDecl = CE->getCalleeDecl();
-  if (CalleeDecl && CalleeDecl->hasAttr<CXX11NoReturnAttr>()) {
-    Diag(St->getBeginLoc(), diag::err_musttail_no_return) << &MTA;
-    return false;
-  }
-
   // Caller and callee must match in whether they have a "this" parameter.
   if (CallerType.This.isNull() != CalleeType.This.isNull()) {
     if (const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {
diff --git a/clang/test/CodeGen/musttail-noreturn.c b/clang/test/CodeGen/musttail-noreturn.c
index 676ad4d051b525..4c22956108ccc2 100644
--- a/clang/test/CodeGen/musttail-noreturn.c
+++ b/clang/test/CodeGen/musttail-noreturn.c
@@ -2,10 +2,16 @@
 
 // A musttail call to a noreturn function must still be followed by a return.
 
+[[noreturn]] void std_noreturn(int);
 __attribute__((noreturn)) void gnu_noreturn(int);
 typedef void noreturn_fn(int) __attribute__((noreturn));
 extern noreturn_fn *noreturn_ptr;
 
+// CHECK-LABEL: define {{.*}} @test_std(
+// CHECK: musttail call void @std_noreturn(
+// CHECK-NEXT: ret void
+void test_std(int x) { [[clang::musttail]] return std_noreturn(x); }
+
 // CHECK-LABEL: define {{.*}} @test_gnu(
 // CHECK: musttail call void @gnu_noreturn(
 // CHECK-NEXT: ret void
diff --git a/clang/test/SemaCXX/PR76631.cpp b/clang/test/SemaCXX/PR76631.cpp
index 0348b9a1bcab56..9061a7d49a6f1a 100644
--- a/clang/test/SemaCXX/PR76631.cpp
+++ b/clang/test/SemaCXX/PR76631.cpp
@@ -5,5 +5,5 @@
 }
 
 void throw_int_wrapper() {
-  [[clang::musttail]] return throw_int(); // expected-error {{'clang::musttail' attribute may not be used with no-return-attribute functions}}
+  [[clang::musttail]] return throw_int();
 }



More information about the llvm-branch-commits mailing list