This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: allow EH to escape from GIMPLE_EH_ELSE ELSE block
- From: Alexandre Oliva <oliva at adacore dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 04 Jul 2019 05:29:11 -0300
- Subject: Re: allow EH to escape from GIMPLE_EH_ELSE ELSE block
- References: <or5zor32gg.fsf@lxoliva.fsfla.org> <CAFiYyc1d_NxUoguzuV4xyNtTmYibJ7bv37zJDJ0sGziW9x=4ug@mail.gmail.com> <orimsq11wa.fsf@lxoliva.fsfla.org> <CAFiYyc10eN+G6ZoN_-QQFpQ4CnSp-NJKoGDFceHWF5pmsON2BA@mail.gmail.com> <oro92cx1jy.fsf@lxoliva.fsfla.org> <CAFiYyc3SL5pYY8_1UCMBR4Nwe5AZHn9Aj_wcX-GVqVpBH1Z=8g@mail.gmail.com>
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.
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