https://gcc.gnu.org/g:9ed526efc2f6ab9d093afe05fa2ad216a10308f0
commit r17-4148-g9ed526efc2f6ab9d093afe05fa2ad216a10308f0 Author: Richard Biener <[email protected]> Date: Thu Sep 10 09:47:33 2026 +0200 Add clobber parsing to the GIMPLE FE 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. 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/ * tree-pretty-print.cc (dump_generic_node): Adjust -gimple dumping for clobbers. gcc/testsuite/ * gcc.dg/gimplefe-60.c: New testcase. Diff: --- 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(-) diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc index 59cb29f420c7..7d374dd66b03 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 000000000000..13e9114496e8 --- /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 ed96728cbc46..89fe93a1f6dc 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, ") ");
