From fdc1f34302906036637445455a53a09f25a4acfd Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 12 Jul 2019 13:50:49 +0000 Subject: [PATCH] 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 --- gcc/c/ChangeLog | 5 +++ gcc/c/gimple-parser.c | 61 ++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/gimplefe-43.c | 25 ++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-43.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c58680c135b..927fa914bfb 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2019-07-12 Alexandre Oliva + + * gimple-parser.c (c_parser_gimple_try_stmt): New. + (c_parser_compound_statement): Call it. + 2019-07-12 Jakub Jelinek * 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 a0ea7215984..4970ae1e9e0 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, "% is not supported"); + else + c_parser_error (parser, "expected % or %"); +} + /* Parse gimple if-else statement. if-statement: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dfda37f912c..c2352005a37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-07-12 Alexandre Oliva + + * gcc.dg/gimplefe-43.c: New. + 2019-07-12 Richard Biener * 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 00000000000..5fd66e6dfa5 --- /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 + { + ; + } +} -- 2.30.2