From d01397347887162a6d5a9d82e750bef91bdba131 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Mon, 10 Nov 2025 11:38:25 -0800 Subject: [PATCH] [WebAssembly] Enable musttail only when tail-call is enabled (#163618) Fixes https://github.com/llvm/llvm-project/issues/163256 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/Basic/Attr.td | 6 +++++- clang/include/clang/Basic/TargetInfo.h | 3 +++ clang/lib/Basic/TargetInfo.cpp | 1 + clang/lib/Basic/Targets/WebAssembly.cpp | 3 +++ clang/test/CodeGen/WebAssembly/musttail.c | 20 ++++++++++++++++++++ 6 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/WebAssembly/musttail.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 98034cfcd8413..72197380cf5af 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1197,6 +1197,8 @@ NetBSD Support WebAssembly Support ^^^^^^^^^^^^^^^^^^^ +- Fix a bug so that ``__has_attribute(musttail)`` is no longer true when WebAssembly's tail-call is not enabled. (#GH163256) + AVR Support ^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 2953c1b63b3dc..26fc0c33eb20e 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -527,6 +527,10 @@ def TargetMicrosoftRecordLayout : TargetArch<["x86", "x86_64", "arm", "thumb", let CustomCode = [{ Target.hasMicrosoftRecordLayout() }]; } +def TargetMustTailAvaiable: TargetSpec { + let CustomCode = [{ Target.hasMustTail() }]; +} + def TargetELF : TargetSpec { let ObjectFormats = ["ELF"]; } @@ -1914,7 +1918,7 @@ def NoMerge : DeclOrStmtAttr { "functions, statements and variables">; } -def MustTail : StmtAttr { +def MustTail : StmtAttr, TargetSpecificAttr { let Spellings = [Clang<"musttail">]; let Documentation = [MustTailDocs]; let Subjects = SubjectList<[ReturnStmt], ErrorDiag, "return statements">; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 76fdb5a2c860d..0ae46f355e7fd 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -229,6 +229,7 @@ class TargetInfo : public TransferrableTargetInfo, protected: // Target values set by the ctor of the actual target implementation. Default // values are specified by the TargetInfo constructor. + bool HasMustTail; bool BigEndian; bool TLSSupported; bool VLASupported; @@ -674,6 +675,8 @@ class TargetInfo : public TransferrableTargetInfo, : getLongFractScale() + 1; } + virtual bool hasMustTail() const { return HasMustTail; } + /// Determine whether the __int128 type is supported on this target. virtual bool hasInt128Type() const { return (getPointerWidth(LangAS::Default) >= 64) || diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 75000dbb804a2..7575eb3fc7f79 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -58,6 +58,7 @@ static const LangASMap FakeAddrSpaceMap = { TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. + HasMustTail = true; BigEndian = !T.isLittleEndian(); TLSSupported = true; VLASupported = true; diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index af25d25a3af3b..910bb28cf1807 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -209,6 +209,7 @@ bool WebAssemblyTargetInfo::initFeatureMap( bool WebAssemblyTargetInfo::handleTargetFeatures( std::vector &Features, DiagnosticsEngine &Diags) { + HasMustTail = false; for (const auto &Feature : Features) { if (Feature == "+atomics") { HasAtomics = true; @@ -333,10 +334,12 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( } if (Feature == "+tail-call") { HasTailCall = true; + HasMustTail = true; continue; } if (Feature == "-tail-call") { HasTailCall = false; + HasMustTail = false; continue; } if (Feature == "+wide-arithmetic") { diff --git a/clang/test/CodeGen/WebAssembly/musttail.c b/clang/test/CodeGen/WebAssembly/musttail.c new file mode 100644 index 0000000000000..37fed70028bbc --- /dev/null +++ b/clang/test/CodeGen/WebAssembly/musttail.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -target-feature +tail-call -o /dev/null -emit-llvm -verify=tail +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -o /dev/null -emit-llvm -verify=notail + +int foo(int x) { + return x; +} + +#if __has_attribute(musttail) +// tail-warning@+1 {{HAS IT}} +#warning HAS IT +#else +// notail-warning@+1 {{DOES NOT HAVE}} +#warning DOES NOT HAVE +#endif + +int bar(int x) +{ + // notail-warning@+1 {{unknown attribute 'clang::musttail' ignored}} + [[clang::musttail]] return foo(1); +}