Skip to content

Commit 5c4083e

Browse files
authored
[WebAssembly] Enable musttail only when tail-call is enabled (#163618)
Fixes #163256
1 parent 0364baf commit 5c4083e

File tree

6 files changed

+34
-1
lines changed

6 files changed

+34
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,8 @@ NetBSD Support
612612
WebAssembly Support
613613
^^^^^^^^^^^^^^^^^^^
614614

615+
- Fix a bug so that ``__has_attribute(musttail)`` is no longer true when WebAssembly's tail-call is not enabled. (#GH163256)
616+
615617
AVR Support
616618
^^^^^^^^^^^
617619

clang/include/clang/Basic/Attr.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,10 @@ def TargetMicrosoftRecordLayout : TargetArch<["x86", "x86_64", "arm", "thumb",
508508
let CustomCode = [{ Target.hasMicrosoftRecordLayout() }];
509509
}
510510

511+
def TargetMustTailAvaiable: TargetSpec {
512+
let CustomCode = [{ Target.hasMustTail() }];
513+
}
514+
511515
def TargetELF : TargetSpec {
512516
let ObjectFormats = ["ELF"];
513517
}
@@ -1913,7 +1917,7 @@ def NoMerge : DeclOrStmtAttr {
19131917
"functions, statements and variables">;
19141918
}
19151919

1916-
def MustTail : StmtAttr {
1920+
def MustTail : StmtAttr, TargetSpecificAttr<TargetMustTailAvaiable> {
19171921
let Spellings = [Clang<"musttail">];
19181922
let Documentation = [MustTailDocs];
19191923
let Subjects = SubjectList<[ReturnStmt], ErrorDiag, "return statements">;

clang/include/clang/Basic/TargetInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ class TargetInfo : public TransferrableTargetInfo,
229229
protected:
230230
// Target values set by the ctor of the actual target implementation. Default
231231
// values are specified by the TargetInfo constructor.
232+
bool HasMustTail;
232233
bool BigEndian;
233234
bool TLSSupported;
234235
bool VLASupported;
@@ -669,6 +670,8 @@ class TargetInfo : public TransferrableTargetInfo,
669670
: getLongFractScale() + 1;
670671
}
671672

673+
virtual bool hasMustTail() const { return HasMustTail; }
674+
672675
/// Determine whether the __int128 type is supported on this target.
673676
virtual bool hasInt128Type() const {
674677
return (getPointerWidth(LangAS::Default) >= 64) ||

clang/lib/Basic/TargetInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static const LangASMap FakeAddrSpaceMap = {
5959
TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
6060
// Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
6161
// SPARC. These should be overridden by concrete targets as needed.
62+
HasMustTail = true;
6263
BigEndian = !T.isLittleEndian();
6364
TLSSupported = true;
6465
VLASupported = true;

clang/lib/Basic/Targets/WebAssembly.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ bool WebAssemblyTargetInfo::initFeatureMap(
213213

214214
bool WebAssemblyTargetInfo::handleTargetFeatures(
215215
std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
216+
HasMustTail = false;
216217
for (const auto &Feature : Features) {
217218
if (Feature == "+atomics") {
218219
HasAtomics = true;
@@ -345,10 +346,12 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
345346
}
346347
if (Feature == "+tail-call") {
347348
HasTailCall = true;
349+
HasMustTail = true;
348350
continue;
349351
}
350352
if (Feature == "-tail-call") {
351353
HasTailCall = false;
354+
HasMustTail = false;
352355
continue;
353356
}
354357
if (Feature == "+wide-arithmetic") {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -target-feature +tail-call -o /dev/null -emit-llvm -verify=tail
2+
// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -o /dev/null -emit-llvm -verify=notail
3+
4+
int foo(int x) {
5+
return x;
6+
}
7+
8+
#if __has_attribute(musttail)
9+
// tail-warning@+1 {{HAS IT}}
10+
#warning HAS IT
11+
#else
12+
// notail-warning@+1 {{DOES NOT HAVE}}
13+
#warning DOES NOT HAVE
14+
#endif
15+
16+
int bar(int x)
17+
{
18+
// notail-warning@+1 {{unknown attribute 'clang::musttail' ignored}}
19+
[[clang::musttail]] return foo(1);
20+
}

0 commit comments

Comments
 (0)