[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