On Thu, Jul 11, 2019 at 12:41 PM Alexandre Oliva <[email protected]> wrote:
>
> On Jul 4, 2019, Richard Biener <[email protected]> wrote:
>
> > Yeah. For other stuff we're simply looking at CPP_NAME and
> > string-matching, see c_parser_gimple_compound_statement
> > where you'd probably hook this into.
>
> Here's a working patch that introduces try/finally[/else] in gimplefe.
> Regstrapped on x86_64-linux-gnu. Ok to install?
OK.
Thanks a lot!
Richard.
> introduce try/finally/else in gimplefe
>
> for gcc/c/ChangeLog
>
> * gimple-parser.c (c_parser_gimple_try_stmt): New.
> (c_parser_compound_statement): Call it.
>
> for gcc/testsuite/ChangeLog
>
> * gcc.dg/gimplefe-43.c: New.
> ---
> gcc/c/gimple-parser.c | 61
> ++++++++++++++++++++++++++++++++++++
> gcc/testsuite/gcc.dg/gimplefe-43.c | 25 +++++++++++++++
> 2 files changed, 86 insertions(+)
> create mode 100644 gcc/testsuite/gcc.dg/gimplefe-43.c
>
> diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
> index a0ea7215984a..4970ae1e9e08 100644
> --- a/gcc/c/gimple-parser.c
> +++ b/gcc/c/gimple-parser.c
> @@ -117,6 +117,7 @@ static struct c_expr
> c_parser_gimple_postfix_expression_after_primary
> static void c_parser_gimple_declaration (gimple_parser &);
> static void c_parser_gimple_goto_stmt (gimple_parser &, location_t,
> tree, gimple_seq *);
> +static void c_parser_gimple_try_stmt (gimple_parser &, gimple_seq *);
> static void c_parser_gimple_if_stmt (gimple_parser &, gimple_seq *);
> static void c_parser_gimple_switch_stmt (gimple_parser &, gimple_seq *);
> static void c_parser_gimple_return_stmt (gimple_parser &, gimple_seq *);
> @@ -407,6 +408,9 @@ c_parser_gimple_compound_statement (gimple_parser
> &parser, gimple_seq *seq)
> case CPP_KEYWORD:
> switch (c_parser_peek_token (parser)->keyword)
> {
> + case RID_AT_TRY:
> + c_parser_gimple_try_stmt (parser, seq);
> + break;
> case RID_IF:
> c_parser_gimple_if_stmt (parser, seq);
> break;
> @@ -448,6 +452,14 @@ c_parser_gimple_compound_statement (gimple_parser
> &parser, gimple_seq *seq)
> c_parser_gimple_label (parser, seq);
> break;
> }
> + if (c_parser_next_token_is (parser, CPP_NAME)
> + && c_parser_peek_token (parser)->id_kind == C_ID_ID
> + && strcmp (IDENTIFIER_POINTER (c_parser_peek_token
> (parser)->value),
> + "try") == 0)
> + {
> + c_parser_gimple_try_stmt (parser, seq);
> + break;
> + }
> /* Basic block specification.
> __BB (index, ...) */
> if ((cfun->curr_properties & PROP_cfg)
> @@ -2092,6 +2104,55 @@ c_parser_gimple_paren_condition (gimple_parser &parser)
> return cond;
> }
>
> +/* Parse gimple try statement.
> +
> + try-statement:
> + try { ... } finally { ... }
> + try { ... } finally { ... } else { ... }
> +
> + This could support try/catch as well, but it's not implemented yet.
> + */
> +
> +static void
> +c_parser_gimple_try_stmt (gimple_parser &parser, gimple_seq *seq)
> +{
> + gimple_seq tryseq = NULL;
> + c_parser_consume_token (parser);
> + c_parser_gimple_compound_statement (parser, &tryseq);
> +
> + if ((c_parser_next_token_is (parser, CPP_KEYWORD)
> + && c_parser_peek_token (parser)->keyword == RID_AT_FINALLY)
> + || (c_parser_next_token_is (parser, CPP_NAME)
> + && c_parser_peek_token (parser)->id_kind == C_ID_ID
> + && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
> + "finally") == 0))
> + {
> + gimple_seq finseq = NULL;
> + c_parser_consume_token (parser);
> + c_parser_gimple_compound_statement (parser, &finseq);
> +
> + if (c_parser_next_token_is (parser, CPP_KEYWORD)
> + && c_parser_peek_token (parser)->keyword == RID_ELSE)
> + {
> + gimple_seq elsseq = NULL;
> + c_parser_consume_token (parser);
> + c_parser_gimple_compound_statement (parser, &elsseq);
> +
> + geh_else *stmt = gimple_build_eh_else (finseq, elsseq);
> + finseq = NULL;
> + gimple_seq_add_stmt_without_update (&finseq, stmt);
> + }
> +
> + gtry *stmt = gimple_build_try (tryseq, finseq, GIMPLE_TRY_FINALLY);
> + gimple_seq_add_stmt_without_update (seq, stmt);
> + }
> + else if (c_parser_next_token_is (parser, CPP_KEYWORD)
> + && c_parser_peek_token (parser)->keyword == RID_AT_CATCH)
> + c_parser_error (parser, "%<catch%> is not supported");
> + else
> + c_parser_error (parser, "expected %<finally%> or %<catch%>");
> +}
> +
> /* Parse gimple if-else statement.
>
> if-statement:
> diff --git a/gcc/testsuite/gcc.dg/gimplefe-43.c
> b/gcc/testsuite/gcc.dg/gimplefe-43.c
> new file mode 100644
> index 000000000000..5fd66e6dfa5c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/gimplefe-43.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fgimple" } */
> +
> +void __GIMPLE foo()
> +{
> + try
> + {
> + try
> + {
> + ;
> + }
> + finally
> + {
> + ;
> + }
> + else
> + {
> + ;
> + }
> + }
> + finally
> + {
> + ;
> + }
> +}
>
>
>
> --
> Alexandre Oliva, freedom fighter he/him https://FSFLA.org/blogs/lxo
> Be the change, be Free! FSF Latin America board member
> GNU Toolchain Engineer Free Software Evangelist
> Hay que enGNUrecerse, pero sin perder la terGNUra jamás - Che GNUevara