On Mon, Jun 03, 2024 at 08:33:52AM -0700, Andi Kleen wrote:
> On Mon, Jun 03, 2024 at 10:42:20AM -0400, Jason Merrill wrote:
> > > @@ -30316,7 +30348,7 @@ cp_parser_std_attribute (cp_parser *parser, tree 
> > > attr_ns)
> > >       /* Maybe we don't expect to see any arguments for this attribute.  
> > > */
> > >       const attribute_spec *as
> > >         = lookup_attribute_spec (TREE_PURPOSE (attribute));
> > > -    if (as && as->max_length == 0)
> > > +    if ((as && as->max_length == 0) || is_attribute_p ("musttail", 
> > > attr_id))
> > 
> > This shouldn't be necessary with the attribute in the c-attribs table,
> > right?  This patch is OK without this hunk and with the comment tweak above.
> 
> Yes I will remove it. Also the hunk above can be simplified, we don't
> need the extra case anymore.
> 
> But unfortunately there's another problem (sorry I missed that earlier
> but the Linaro bot pointed it out again):
> 
> This hunk:
> 
> @@ -21085,12 +21085,14 @@ 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 = 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;
> +               CALL_EXPR_MUST_TAIL_CALL (call) = mtc;
>               }

The difference is that CALL_EXPR_MUST_TAIL_CALL is defined as:
#define CALL_EXPR_MUST_TAIL_CALL(NODE) \
  (CALL_EXPR_CHECK (NODE)->base.static_flag)
while the others like:
#define CALL_EXPR_ORDERED_ARGS(NODE) \
  TREE_LANG_FLAG_3 (CALL_OR_AGGR_INIT_CHECK (NODE))
where
#define CALL_OR_AGGR_INIT_CHECK(NODE) \
  TREE_CHECK2 ((NODE), CALL_EXPR, AGGR_INIT_EXPR)
while
#define CALL_EXPR_CHECK(t)      TREE_CHECK (t, CALL_EXPR)
(this one is defined in generated tree-check.h).
So, while the CALL_EXPR_REVERSE_ARGS etc. can be used on either
CALL_EXPR or AGGR_INIT_EXPR (the latter is a C++ specific tree code),
CALL_EXPR_MUST_TAIL_CALL is allowed only on CALL_EXPR.
AGGR_INIT_EXPR is used for C++ constructor calls, so I think
they really don't need such a flag, so you could do:
            bool mtc = (TREE_CODE (t) == CALL_EXPR
                        ? CALL_EXPR_MUST_TAIL_CALL (t) : false);
            if (op || ord || rev || mtc)
...
              if (mtc)
                CALL_EXPR_MUST_TAIL_CALL (call) = 1;
or something similar.
Or you'd need to define a variant of the CALL_EXPR_MUST_TAIL_CALL
macro for the C++ FE (as CALL_OR_AGGR_INIT_CHECK is C++ FE too)
and use that in the FE and somehow assert it means the same thing
as the middle-end flag except that it can be also used on AGGR_INIT_EXPR.

        Jakub

Reply via email to