On 7/15/24 11:24 PM, Andi Kleen wrote:
On Mon, Jul 15, 2024 at 06:57:57PM -0400, Jason Merrill wrote:
On 7/8/24 12:56 PM, Andi Kleen wrote:
diff --git a/gcc/testsuite/g++.dg/musttail10.C
b/gcc/testsuite/g++.dg/musttail10.C
new file mode 100644
index 000000000000..9b7043b8a306
--- /dev/null
+++ b/gcc/testsuite/g++.dg/musttail10.C
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { tail_call } } } */
+/* { dg-options "-std=gnu++11" } */
+/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
+
+int f();
+
+double h() { [[gnu::musttail]] return f(); } /* { dg-error "cannot tail-call"
} */
+
+template <class T>
+__attribute__((noinline, noclone, noipa))
+T g1() { [[gnu::musttail]] return f(); } /* { dg-error "target is not able" ""
{ target powerpc*-*-* } } */
+
+template <class T>
+__attribute__((noinline, noclone, noipa))
+T g2() { [[gnu::musttail]] return f(); } /* { dg-error "cannot tail-call" } */
+
+template <class T>
+__attribute__((noinline, noclone, noipa))
+T g3() { [[gnu::musttail]] return f(); } /* { dg-error "cannot tail-call" } */
+
+class C
+{
+ double x;
+public:
+ C(double x) : x(x) {}
+ ~C() { asm("":::"memory"); }
+};
+
+int main()
+{
+ g1<int>();
+ g2<double>();
+ g3<C>();
+}
I had asked for this test to check the case where the function called with
[[musttail]] returns a non-trivially-copyable class; the test now includes
such a class, but all the [[musttail]] calls are still to a function that
returns int.
Thanks Jason.
I fixed the test case, but now the musttail gets lost, no error for g2/g3.
That means the flag is still lost somewhere. Does something outside tsubst need
changes too?
Right now tsubst has only this:
@@ -21113,12 +21113,17 @@ tsubst_expr (tree t, tree args, tsubst_flags_t
complain, tree in_decl)
bool op = CALL_EXPR_OPERATOR_SYNTAX (t);
bool ord = CALL_EXPR_ORDERED_ARGS (t);
bool rev = CALL_EXPR_REVERSE_ARGS (t);
- if (op || ord || rev)
+ bool mtc = false;
+ if (TREE_CODE (t) == CALL_EXPR)
+ mtc = CALL_EXPR_MUST_TAIL_CALL (t);
+ if (op || ord || rev || mtc)
if (tree call = extract_call_expr (ret))
{
CALL_EXPR_OPERATOR_SYNTAX (call) = op;
CALL_EXPR_ORDERED_ARGS (call) = ord;
CALL_EXPR_REVERSE_ARGS (call) = rev;
+ if (TREE_CODE (call) == CALL_EXPR)
+ CALL_EXPR_MUST_TAIL_CALL (call) = mtc;
}
if (warning_suppressed_p (t, OPT_Wpessimizing_move))
/* This also suppresses -Wredundant-move. */
Fixed test case:
template <class T> T f();
double h() { [[gnu::musttail]] return f<int>(); } /* { dg-error "cannot
tail-call" } */
template <class T>
__attribute__((noinline, noclone, noipa))
T g1() { [[gnu::musttail]] return f<T>(); } /* { dg-error "target is not able"
"" { target powerpc*-*-* } } */
template <class T>
__attribute__((noinline, noclone, noipa))
T g2() { [[gnu::musttail]] return f<T>(); } /* { dg-error "cannot tail-call" }
*/
template <class T>
__attribute__((noinline, noclone, noipa))
T g3() { [[gnu::musttail]] return f<T>(); } /* { dg-error "cannot tail-call" }
*/
In the adjusted test it looks like the types of f and g match, so I
wouldn't expect an error.
class C
{
double x;
public:
C(double x) : x(x) {}
~C() { asm("":::"memory"); }
};
int main()
{
g1<int>();
g2<double>();
g3<C>();
}