Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -546,6 +546,8 @@ NetBSD Support
WebAssembly Support
^^^^^^^^^^^^^^^^^^^

- Fix a bug so that __has_attribute(musttail) should not be true anymore when notail is not enabled.

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 @@ -508,6 +508,10 @@ def TargetMicrosoftRecordLayout : TargetArch<["x86", "x86_64", "arm", "thumb",
let CustomCode = [{ Target.hasMicrosoftRecordLayout() }];
}

def TargetMustTailAvaiable: TargetSpec {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def TargetMustTailAvaiable: TargetSpec {
def TargetMustTailAvailable: TargetSpec {

let CustomCode = [{ Target.hasMustTail() }];
}

def TargetELF : TargetSpec {
let ObjectFormats = ["ELF"];
}
Expand Down Expand Up @@ -1896,7 +1900,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 @@ -669,6 +670,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 @@ -59,6 +59,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 @@ -213,6 +213,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 @@ -345,10 +346,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);
}