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 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


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