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