This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: allow EH to escape from GIMPLE_EH_ELSE ELSE block


On Thu, Jul 4, 2019 at 10:29 AM Alexandre Oliva <oliva@adacore.com> wrote:
>
> On Jul  2, 2019, Richard Biener <richard.guenther@gmail.com> wrote:
>
> > Yeah, it's on trunk.  The parser is ontop of the C frontend and resides
> > in gcc/c/gimple-parser.c while testcases are in gcc.dg/gimplefe-*.c
>
> > The parsing is incomplete, there's no support for parsing try/catch/finally
>
> I'm afraid I haven't got very far, but I tried.  It didn't recognize try
> and finally as keywords, and since the parser is integrated with the C
> parser IIUC, I wasn't sure how to enable the keywords only within gimple
> functions.

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.



> As mentioned in another message, I chose try/finally/else as the
> notation for TRY_FINALLY_EXPR <..., EH_ELSE_EXPR <..., ...> >, to avoid
> introducing yet another keyword such as eh_finally.
>
> I also considered try/noexcept/finally, or try/noexcept finally/finally,
> but...  else seems to be a lot more closely related with EH_ELSE_EXPR,
> and at least in gimple it's non-ambiguous.
>
>
> introduce try/finally/else in gimplefe (WIP FTR)
>
> From: Alexandre Oliva <oliva@adacore.com>
>
>
> ---
>  gcc/c/gimple-parser.c              |   49 ++++++++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/gimplefe-43.c |   13 ++++++++++
>  2 files changed, 62 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 b2b364cc41a3..91f2499bb1cc 100644
> --- a/gcc/c/gimple-parser.c
> +++ b/gcc/c/gimple-parser.c
> @@ -115,6 +115,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 *);
> @@ -405,6 +406,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;
> @@ -2088,6 +2092,51 @@ 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)
> +    {
> +      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, &finseq);
> +
> +         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..c740e06a78e1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/gimplefe-43.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fgimple" } */
> +
> +void __GIMPLE foo()
> +{
> +  try {
> +    ;
> +  } finally {
> +    ;
> +  } else {
> +    ;
> +  }
> +}
>
>
> --
> 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]