Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^

Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
}
Expand Down Expand Up @@ -1914,7 +1918,7 @@ def NoMerge : DeclOrStmtAttr {
"functions, statements and variables">;
}

def MustTail : StmtAttr {
def MustTail : StmtAttr, TargetSpecificAttr<TargetMustTailAvaiable> {
let Spellings = [Clang<"musttail">];
let Documentation = [MustTailDocs];
let Subjects = SubjectList<[ReturnStmt], ErrorDiag, "return statements">;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) ||
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ bool WebAssemblyTargetInfo::initFeatureMap(

bool WebAssemblyTargetInfo::handleTargetFeatures(
std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
HasMustTail = false;
for (const auto &Feature : Features) {
if (Feature == "+atomics") {
HasAtomics = true;
Expand Down Expand Up @@ -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") {
Expand Down
20 changes: 20 additions & 0 deletions clang/test/CodeGen/WebAssembly/musttail.c
Original file line number Diff line number Diff line change
@@ -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);
}