xbolva00 updated this revision to Diff 511498.
xbolva00 added a comment.
Herald added subscribers: llvm-commits, pengfei, hiraditya.
Herald added a project: LLVM.
Added location when emiting diagnostic about failed TCO in the backend.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D147714/new/
https://reviews.llvm.org/D147714
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaStmt.cpp
clang/test/SemaCXX/attr-musttail.cpp
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/tailcc-notail.ll
Index: llvm/test/CodeGen/X86/tailcc-notail.ll
===================================================================
--- llvm/test/CodeGen/X86/tailcc-notail.ll
+++ llvm/test/CodeGen/X86/tailcc-notail.ll
@@ -1,6 +1,6 @@
; RUN: not --crash llc -mtriple=x86_64-linux-gnu %s -o - 2>&1 | FileCheck %s
-; CHECK: LLVM ERROR: failed to perform tail call elimination on a call site marked musttail
+; CHECK: error: {{.*}} in function caller {{.*}}: failed to perform tail call elimination on a call site marked musttail
declare tailcc [16 x i64] @callee()
define tailcc [16 x i64] @caller() {
%res = musttail call tailcc [16 x i64] @callee()
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -4507,7 +4507,7 @@
}
if (IsMustTail && !isTailCall)
- report_fatal_error("failed to perform tail call elimination on a call "
+ errorUnsupported(DAG, dl, "failed to perform tail call elimination on a call "
"site marked musttail");
assert(!(isVarArg && canGuaranteeTCO(CallConv)) &&
Index: clang/test/SemaCXX/attr-musttail.cpp
===================================================================
--- clang/test/SemaCXX/attr-musttail.cpp
+++ clang/test/SemaCXX/attr-musttail.cpp
@@ -6,6 +6,7 @@
[[clang::musttail(1, 2)]] return ReturnsInt1(); // expected-error {{'musttail' attribute takes no arguments}}
[[clang::musttail]] return 5; // expected-error {{'musttail' attribute requires that the return value is the result of a function call}}
[[clang::musttail]] return ReturnsInt1();
+ [[clang::nonportable_musttail]] return ReturnsInt1();
}
void NoFunctionCall() {
@@ -20,6 +21,11 @@
return NoParams(); // expected-error {{cannot perform a tail call to function 'NoParams' because its signature is incompatible with the calling function}}
}
+void TestParamArityMismatchNonPortable(int x) {
+ [[clang::nonportable_musttail]]
+ return NoParams();
+}
+
void LongParam(long x); // expected-note {{target function has type mismatch at 1st parameter (expected 'long' but has 'int')}}
void TestParamTypeMismatch(int x) {
[[clang::musttail]] // expected-note {{tail call required by 'musttail' attribute here}}
@@ -267,3 +273,17 @@
void TestCallNonValue() {
[[clang::musttail]] return ns; // expected-error {{unexpected namespace name 'ns': expected expression}}
}
+
+struct Foo {
+ int foo(int) { return 0; }
+};
+
+struct Bar {
+ Foo foo;
+ int bar(int);
+};
+
+int Bar::bar(int x) {
+ [[clang::nonportable_musttail]]
+ return foo.foo(x);
+}
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -586,7 +586,7 @@
// attributes lands.
for (const auto *A : Attrs) {
if (A->getKind() == attr::MustTail) {
- if (!checkAndRewriteMustTailAttr(SubStmt, *A)) {
+ if (!checkAndRewriteMustTailAttr(SubStmt, *cast<MustTailAttr>(A))) {
return SubStmt;
}
setFunctionHasMustTail();
@@ -608,7 +608,7 @@
return SubStmt;
}
-bool Sema::checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA) {
+bool Sema::checkAndRewriteMustTailAttr(Stmt *St, const MustTailAttr &MTA) {
ReturnStmt *R = cast<ReturnStmt>(St);
Expr *E = R->getRetValue();
@@ -633,7 +633,7 @@
return true;
}
-bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
+bool Sema::checkMustTailAttr(const Stmt *St, const MustTailAttr &MTA) {
assert(!CurContext->isDependentContext() &&
"musttail cannot be checked from a dependent context");
@@ -846,6 +846,9 @@
return true;
};
+ if (MTA.isNonPortableMustTail())
+ return true;
+
PartialDiagnostic PD = PDiag(diag::note_musttail_mismatch);
if (!CheckTypesMatch(CallerType, CalleeType, PD)) {
if (const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -12351,12 +12351,12 @@
/// issuing a diagnostic and returning false if not. In the success case,
/// the statement is rewritten to remove implicit nodes from the return
/// value.
- bool checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA);
+ bool checkAndRewriteMustTailAttr(Stmt *St, const MustTailAttr &MTA);
private:
/// Check whether the given statement can have musttail applied to it,
/// issuing a diagnostic and returning false if not.
- bool checkMustTailAttr(const Stmt *St, const Attr &MTA);
+ bool checkMustTailAttr(const Stmt *St, const MustTailAttr &MTA);
public:
/// Check to see if a given expression could have '.c_str()' called on it.
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -605,7 +605,8 @@
old style K&R C function declarations.
``clang::musttail`` provides assurances that the tail call can be optimized on
-all targets, not just one.
+all targets, not just one. If you care about one target and you do not need
+these assurances, use ``clang::nonportable_musttail``.
}];
}
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1470,8 +1470,9 @@
}
def MustTail : StmtAttr {
- let Spellings = [Clang<"musttail">];
+ let Spellings = [Clang<"musttail">, Clang<"nonportable_musttail">];
let Documentation = [MustTailDocs];
+ let Accessors = [Accessor<"isNonPortableMustTail", [Clang<"nonportable_musttail">]>];
let Subjects = SubjectList<[ReturnStmt], ErrorDiag, "return statements">;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits