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" } 
*/

class C
{
  double x;
public:
  C(double x) : x(x) {}
  ~C() { asm("":::"memory"); }
};

int main()
{
  g1<int>();
  g2<double>();
  g3<C>();
}

Reply via email to