aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2019-07-12 13:50:49 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2019-07-12 13:50:49 +0000
commitfdc1f34302906036637445455a53a09f25a4acfd (patch)
tree6699885ac98338fa7078d87d30d5e4787d6ae1a1
parent0d67cd380d37f2a28156d3430b9964a5df67a101 (diff)
downloadgcc-fdc1f34302906036637445455a53a09f25a4acfd.zip
gcc-fdc1f34302906036637445455a53a09f25a4acfd.tar.gz
gcc-fdc1f34302906036637445455a53a09f25a4acfd.tar.bz2
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. From-SVN: r273443
-rw-r--r--gcc/c/ChangeLog5
-rw-r--r--gcc/c/gimple-parser.c61
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/gimplefe-43.c25
4 files changed, 95 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index c58680c..927fa91 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,8 @@
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
+
+ * gimple-parser.c (c_parser_gimple_try_stmt): New.
+ (c_parser_compound_statement): Call it.
+
2019-07-12 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (c_parser_omp_clause_name): Handle order clause.
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index a0ea721..4970ae1 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/ChangeLog b/gcc/testsuite/ChangeLog
index dfda37f..c235200 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/gimplefe-43.c: New.
+
2019-07-12 Richard Biener <rguenther@suse.de>
* gcc.dg/tree-ssa/vector-7.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/gimplefe-43.c b/gcc/testsuite/gcc.dg/gimplefe-43.c
new file mode 100644
index 0000000..5fd66e6
--- /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
+ {
+ ;
+ }
+}