introduce try/finally/else in gimplefe
authorAlexandre Oliva <oliva@adacore.com>
Fri, 12 Jul 2019 13:50:49 +0000 (13:50 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 12 Jul 2019 13:50:49 +0000 (13:50 +0000)
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

gcc/c/ChangeLog
gcc/c/gimple-parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/gimplefe-43.c [new file with mode: 0644]

index c58680c135b541c35ae39299b98c233fe004b117..927fa914bfb6581b29dfb6fc9f272a33e85fca1e 100644 (file)
@@ -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.
index a0ea7215984ab01074c5622428ee4d28d25106ec..4970ae1e9e086fb8aca2c533943ff3eb60fcca98 100644 (file)
@@ -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:
index dfda37f912c0df24ab73517be524594c1afaeff2..c2352005a370bcdd0104cd1655989949e20b55b4 100644 (file)
@@ -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 (file)
index 0000000..5fd66e6
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+void __GIMPLE foo()
+{
+  try
+    {
+      try
+       {
+         ;
+       }
+      finally
+       {
+         ;
+       }
+      else
+       {
+         ;
+       }
+    }
+  finally
+    {
+      ;
+    }
+}