On Thu, Sep 10, 2026 at 1:19 AM Richard Biener <[email protected]> wrote:
>
> The following adds parsing of clobbers to the GIMPLE FE. Rather
> than parsing { CLOBBER [(bob|bos|eob|eos)] } with the CLOBBER
> identifier uglified I've changed this to __CLOBBER [ (bob|bos|eob|eos) ]
> which also does not expose the CONSTRUCTOR implementation detail.
> The type of the clobber is infered from the LHS.
>
> Parsing of {v} in the assignment is not implemented as part of this
> and it should not be necessary as it's infered from the LHS/RHS
> by the operand scanner (so it's redundant info). It's still
> printed with -gimple dumping.
>
> I hope to eventually switch non -gimple dumping to the -gimple
> dumping syntax for some bits like __MEM dumping and this would
> also be a candidate.
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
>
> Any comments?
LGTM. I had almost filed a bug asking about adding this support but I
didn't need it at the time so I didn't.
>
> Thanks,
> Richard.
>
> gcc/c/
> * gimple-parser.cc (c_parser_gimple_postfix_expression):
> Add ret_type argument, defaulted to error_mark_node.
> Add parsing of __CLOBBER.
> (c_parser_gimple_binary_expression): Pass ret_type down to
> c_parser_gimple_postfix_expression.
>
> gcc/testsuite/
> * gcc.dg/gimplefe-60.c: New testcase.
> ---
> gcc/c/gimple-parser.cc | 39 +++++++++++++++++++++++++++---
> gcc/testsuite/gcc.dg/gimplefe-60.c | 16 ++++++++++++
> gcc/tree-pretty-print.cc | 22 +++++++++++++++++
> 3 files changed, 74 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/gimplefe-60.c
>
> diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
> index 59cb29f420c..7d374dd66b0 100644
> --- a/gcc/c/gimple-parser.cc
> +++ b/gcc/c/gimple-parser.cc
> @@ -110,7 +110,8 @@ static void c_parser_gimple_label (gimple_parser &,
> gimple_seq *);
> static void c_parser_gimple_statement (gimple_parser &, gimple_seq *);
> static struct c_expr c_parser_gimple_binary_expression (gimple_parser &,
> tree);
> static struct c_expr c_parser_gimple_unary_expression (gimple_parser &);
> -static struct c_expr c_parser_gimple_postfix_expression (gimple_parser &);
> +static struct c_expr c_parser_gimple_postfix_expression
> + (gimple_parser &, tree = error_mark_node);
> static struct c_expr c_parser_gimple_postfix_expression_after_primary
> (gimple_parser &, location_t, struct c_expr);
> static void c_parser_gimple_declaration (gimple_parser &);
> @@ -1023,7 +1024,7 @@ c_parser_gimple_binary_expression (gimple_parser
> &parser, tree ret_type)
> struct c_expr ret, lhs, rhs;
> enum tree_code code = ERROR_MARK;
> ret.set_error ();
> - lhs = c_parser_gimple_postfix_expression (parser);
> + lhs = c_parser_gimple_postfix_expression (parser, ret_type);
> if (c_parser_error (parser))
> return ret;
> switch (c_parser_peek_token (parser)->type)
> @@ -1488,7 +1489,7 @@ c_parser_gimple_typespec (gimple_parser &parser)
> */
>
> static struct c_expr
> -c_parser_gimple_postfix_expression (gimple_parser &parser)
> +c_parser_gimple_postfix_expression (gimple_parser &parser, tree ret_type)
> {
> location_t loc = c_parser_peek_token (parser)->location;
> source_range tok_range = c_parser_peek_token (parser)->get_range ();
> @@ -1752,6 +1753,38 @@ c_parser_gimple_postfix_expression (gimple_parser
> &parser)
> }
> break;
> }
> + else if (strcmp (IDENTIFIER_POINTER (id), "__CLOBBER") == 0)
> + {
> + /* __CLOBBER [ '(' bob | eob | bos | eos ')' ] */
> + clobber_kind kind = CLOBBER_UNDEF;
> + c_parser_consume_token (parser);
> + if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
> + {
> + c_parser_consume_token (parser);
> + auto tok = c_parser_peek_token (parser);
> + if (c_parser_require (parser, CPP_NAME,
> + "expected clobber kind"))
> + {
> + const char *kind_str = IDENTIFIER_POINTER (tok->value);
> + if (strcmp (kind_str, "bos") == 0)
> + kind = CLOBBER_STORAGE_BEGIN;
> + else if (strcmp (kind_str, "bob") == 0)
> + kind = CLOBBER_OBJECT_BEGIN;
> + else if (strcmp (kind_str, "eob") == 0)
> + kind = CLOBBER_OBJECT_END;
> + else if (strcmp (kind_str, "eos") == 0)
> + kind = CLOBBER_STORAGE_END;
> + else
> + c_parser_error (parser, "expected one of %<bos%>, "
> + "%<eos%>, %<bob>, %<eob%>");
> + }
> + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
> + "expected %<)%>");
> + }
> + /* We infer the (redundant) type from the LHS. */
> + expr.value = build_clobber (ret_type, kind);
> + break;
> + }
> else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
> {
> /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor
> ) */
> diff --git a/gcc/testsuite/gcc.dg/gimplefe-60.c
> b/gcc/testsuite/gcc.dg/gimplefe-60.c
> new file mode 100644
> index 00000000000..13e9114496e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/gimplefe-60.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fgimple" } */
> +
> +struct X { int i; };
> +
> +void __GIMPLE
> +foo ()
> +{
> + struct X x;
> + x = __CLOBBER;
> + x = __CLOBBER(bos);
> + x = __CLOBBER (eos);
> + x = __CLOBBER(bob);
> + x = __CLOBBER(eob);
> + return;
> +}
> diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
> index ed96728cbc4..89fe93a1f6d 100644
> --- a/gcc/tree-pretty-print.cc
> +++ b/gcc/tree-pretty-print.cc
> @@ -3047,6 +3047,28 @@ dump_generic_node (pretty_printer *pp, tree node, int
> spc, dump_flags_t flags,
> widest_int curidx;
> if (flags & TDF_GIMPLE)
> {
> + if (TREE_CLOBBER_P (node))
> + {
> + pp_string (pp, "__CLOBBER");
> + switch (CLOBBER_KIND (node))
> + {
> + case CLOBBER_STORAGE_BEGIN:
> + pp_string (pp, "(bos)");
> + break;
> + case CLOBBER_STORAGE_END:
> + pp_string (pp, "(eos)");
> + break;
> + case CLOBBER_OBJECT_BEGIN:
> + pp_string (pp, "(bob)");
> + break;
> + case CLOBBER_OBJECT_END:
> + pp_string (pp, "(eob)");
> + break;
> + default:
> + break;
> + }
> + break;
> + }
> pp_string (pp, "_Literal (");
> dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
> pp_string (pp, ") ");
> --
> 2.51.0
>