This corresponds to: [PATCH 32/89] Introduce gimple_try https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01214.html from the original 89-patch kit
That earlier patch was approved by Jeff: > OK once const and associated renaming stuff is fixed. in https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00636.html gcc/ * coretypes.h (gimple_try): New typedef. (const_gimple_try): New typedef. * gimple-low.c (gimple_try_catch_may_fallthru): Require a gimple_try rather than a plain gimple. (gimple_stmt_may_fallthru): Add checked cast to gimple_try. * gimple-pretty-print.c (dump_gimple_try): Require a gimple_try rather than a plain gimple. (pp_gimple_stmt_1): Add checked cast to gimple_try within GIMPLE_TRY case of switch statement. * tree-eh.c (finally_tree_node::parent): Strengthen field from gimple to gimple_try. (record_in_finally_tree): Require a gimple_try rather than a plain gimple. (collect_finally_tree): Likewise. (collect_finally_tree_1): Likewise. (struct leh_tf_state::try_finally_expr): Strengthen field from gimple to gimple_try. (struct leh_tf_state::top_p): Likewise. (lower_eh_must_not_throw): Require a gimple_try rather than a plain gimple. (frob_into_branch_around): Likewise. (lower_try_finally_dup_block): Strengthen local from gimple to gimple_try. (honor_protect_cleanup_actions): Split out uses of "x" into new locals "eh_mnt" and "try_stmt" with stronger types. (lower_try_finally): Require a gimple_try rather than a plain gimple. (lower_catch): Likewise. (lower_eh_filter): Likewise. (lower_eh_must_not_throw): Likewise. (lower_cleanup): Likewise. (lower_eh_constructs_2): Add checked cast to gimple_try within GIMPLE_TRY case of switch statement, introducing new local "try_stmt", using it for type-safety. --- gcc/ChangeLog.gimple-classes | 42 ++++++++++++++++++++ gcc/coretypes.h | 4 ++ gcc/gimple-low.c | 4 +- gcc/gimple-pretty-print.c | 4 +- gcc/tree-eh.c | 94 +++++++++++++++++++++++--------------------- 5 files changed, 100 insertions(+), 48 deletions(-) diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes index afdccbe..983819a 100644 --- a/gcc/ChangeLog.gimple-classes +++ b/gcc/ChangeLog.gimple-classes @@ -1,5 +1,47 @@ 2014-10-24 David Malcolm <dmalc...@redhat.com> + Introduce gimple_try + + * coretypes.h (gimple_try): New typedef. + (const_gimple_try): New typedef. + + * gimple-low.c (gimple_try_catch_may_fallthru): Require a + gimple_try rather than a plain gimple. + (gimple_stmt_may_fallthru): Add checked cast to gimple_try. + + * gimple-pretty-print.c (dump_gimple_try): Require a gimple_try + rather than a plain gimple. + (pp_gimple_stmt_1): Add checked cast to gimple_try within + GIMPLE_TRY case of switch statement. + + * tree-eh.c (finally_tree_node::parent): Strengthen field from + gimple to gimple_try. + (record_in_finally_tree): Require a gimple_try rather than a plain + gimple. + (collect_finally_tree): Likewise. + (collect_finally_tree_1): Likewise. + (struct leh_tf_state::try_finally_expr): Strengthen field from + gimple to gimple_try. + (struct leh_tf_state::top_p): Likewise. + (lower_eh_must_not_throw): Require a gimple_try rather than a + plain gimple. + (frob_into_branch_around): Likewise. + (lower_try_finally_dup_block): Strengthen local from gimple to + gimple_try. + (honor_protect_cleanup_actions): Split out uses of "x" into new + locals "eh_mnt" and "try_stmt" with stronger types. + (lower_try_finally): Require a gimple_try rather than a plain + gimple. + (lower_catch): Likewise. + (lower_eh_filter): Likewise. + (lower_eh_must_not_throw): Likewise. + (lower_cleanup): Likewise. + (lower_eh_constructs_2): Add checked cast to gimple_try within + GIMPLE_TRY case of switch statement, introducing new local + "try_stmt", using it for type-safety. + +2014-10-24 David Malcolm <dmalc...@redhat.com> + Use subclasses of gimple in various places * asan.c (insert_if_then_before_iter): Require a gimple cond diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 6914027..e24a08e 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -162,6 +162,10 @@ struct gimple_statement_phi; typedef struct gimple_statement_phi *gimple_phi; typedef const struct gimple_statement_phi *const_gimple_phi; +struct gimple_statement_try; +typedef struct gimple_statement_try *gimple_try; +typedef const struct gimple_statement_try *const_gimple_try; + union section; typedef union section section; struct gcc_options; diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index b5dc823..a9121aa 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -499,7 +499,7 @@ lower_try_catch (gimple_stmt_iterator *gsi, struct lower_data *data) This is a subroutine of gimple_stmt_may_fallthru. */ static bool -gimple_try_catch_may_fallthru (gimple stmt) +gimple_try_catch_may_fallthru (gimple_try stmt) { gimple_stmt_iterator i; @@ -585,7 +585,7 @@ gimple_stmt_may_fallthru (gimple stmt) case GIMPLE_TRY: if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH) - return gimple_try_catch_may_fallthru (stmt); + return gimple_try_catch_may_fallthru (as_a <gimple_try> (stmt)); /* It must be a GIMPLE_TRY_FINALLY. */ diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 00ff34c..a1db8be 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -932,7 +932,7 @@ dump_gimple_bind (pretty_printer *buffer, gimple_bind gs, int spc, int flags) dumpfile.h). */ static void -dump_gimple_try (pretty_printer *buffer, gimple gs, int spc, int flags) +dump_gimple_try (pretty_printer *buffer, gimple_try gs, int spc, int flags) { if (flags & TDF_RAW) { @@ -2128,7 +2128,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) break; case GIMPLE_TRY: - dump_gimple_try (buffer, gs, spc, flags); + dump_gimple_try (buffer, as_a <gimple_try> (gs), spc, flags); break; case GIMPLE_PHI: diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 5a83f3f..e45f234 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -177,7 +177,7 @@ struct finally_tree_node tree) leaves the TRY block, its necessary to record a tree in this field. Thus a treemple is used. */ treemple child; - gimple parent; + gimple_try parent; }; /* Hashtable helpers. */ @@ -206,7 +206,7 @@ finally_tree_hasher::equal (const value_type *v, const compare_type *c) static hash_table<finally_tree_hasher> *finally_tree; static void -record_in_finally_tree (treemple child, gimple parent) +record_in_finally_tree (treemple child, gimple_try parent) { struct finally_tree_node *n; finally_tree_node **slot; @@ -221,13 +221,13 @@ record_in_finally_tree (treemple child, gimple parent) } static void -collect_finally_tree (gimple stmt, gimple region); +collect_finally_tree (gimple stmt, gimple_try region); /* Go through the gimple sequence. Works with collect_finally_tree to record all GIMPLE_LABEL and GIMPLE_TRY statements. */ static void -collect_finally_tree_1 (gimple_seq seq, gimple region) +collect_finally_tree_1 (gimple_seq seq, gimple_try region) { gimple_stmt_iterator gsi; @@ -236,7 +236,7 @@ collect_finally_tree_1 (gimple_seq seq, gimple region) } static void -collect_finally_tree (gimple stmt, gimple region) +collect_finally_tree (gimple stmt, gimple_try region) { treemple temp; @@ -252,7 +252,8 @@ collect_finally_tree (gimple stmt, gimple region) { temp.g = stmt; record_in_finally_tree (temp, region); - collect_finally_tree_1 (gimple_try_eval (stmt), stmt); + collect_finally_tree_1 (gimple_try_eval (stmt), + as_a <gimple_try> (stmt)); collect_finally_tree_1 (gimple_try_cleanup (stmt), region); } else if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH) @@ -369,8 +370,8 @@ struct leh_tf_state try_finally_expr is the original GIMPLE_TRY_FINALLY. We need to retain this so that outside_finally_tree can reliably reference the tree used in the collect_finally_tree data structures. */ - gimple try_finally_expr; - gimple top_p; + gimple_try try_finally_expr; + gimple_try top_p; /* While lowering a top_p usually it is expanded into multiple statements, thus we need the following field to store them. */ @@ -410,7 +411,7 @@ struct leh_tf_state bool may_throw; }; -static gimple_seq lower_eh_must_not_throw (struct leh_state *, gimple); +static gimple_seq lower_eh_must_not_throw (struct leh_state *, gimple_try); /* Search for STMT in the goto queue. Return the replacement, or null if the statement isn't in the queue. */ @@ -861,7 +862,7 @@ eh_region_may_contain_throw (eh_region r) an existing label that should be put at the exit, or NULL. */ static gimple_seq -frob_into_branch_around (gimple tp, eh_region region, tree over) +frob_into_branch_around (gimple_try tp, eh_region region, tree over) { gimple x; gimple_seq cleanup, result; @@ -898,7 +899,7 @@ static gimple_seq lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state, location_t loc) { - gimple region = NULL; + gimple_try region = NULL; gimple_seq new_seq; gimple_stmt_iterator gsi; @@ -990,6 +991,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, bool finally_may_fallthru; gimple_seq finally; gimple x; + gimple_eh_must_not_throw eh_mnt; + gimple_try try_stmt; gimple_eh_else eh_else; /* First check for nothing to do. */ @@ -1032,10 +1035,10 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, } /* Wrap the block with protect_cleanup_actions as the action. */ - x = gimple_build_eh_must_not_throw (protect_cleanup_actions); - x = gimple_build_try (finally, gimple_seq_alloc_with_stmt (x), - GIMPLE_TRY_CATCH); - finally = lower_eh_must_not_throw (outer_state, x); + eh_mnt = gimple_build_eh_must_not_throw (protect_cleanup_actions); + try_stmt = gimple_build_try (finally, gimple_seq_alloc_with_stmt (eh_mnt), + GIMPLE_TRY_CATCH); + finally = lower_eh_must_not_throw (outer_state, try_stmt); /* Drop all of this into the exception sequence. */ emit_post_landing_pad (&eh_seq, tf->region); @@ -1640,7 +1643,7 @@ cleanup_is_dead_in (eh_region reg) arrange for the FINALLY block to be executed on all exits. */ static gimple_seq -lower_try_finally (struct leh_state *state, gimple tp) +lower_try_finally (struct leh_state *state, gimple_try tp) { struct leh_tf_state this_tf; struct leh_state this_state; @@ -1747,7 +1750,7 @@ lower_try_finally (struct leh_state *state, gimple tp) exception region trees that records all the magic. */ static gimple_seq -lower_catch (struct leh_state *state, gimple tp) +lower_catch (struct leh_state *state, gimple_try tp) { eh_region try_region = NULL; struct leh_state this_state = *state; @@ -1819,7 +1822,7 @@ lower_catch (struct leh_state *state, gimple tp) region trees that record all the magic. */ static gimple_seq -lower_eh_filter (struct leh_state *state, gimple tp) +lower_eh_filter (struct leh_state *state, gimple_try tp) { struct leh_state this_state = *state; eh_region this_region = NULL; @@ -1864,7 +1867,7 @@ lower_eh_filter (struct leh_state *state, gimple tp) plus the exception region trees that record all the magic. */ static gimple_seq -lower_eh_must_not_throw (struct leh_state *state, gimple tp) +lower_eh_must_not_throw (struct leh_state *state, gimple_try tp) { struct leh_state this_state = *state; @@ -1897,7 +1900,7 @@ lower_eh_must_not_throw (struct leh_state *state, gimple tp) except that we only execute the cleanup block for exception edges. */ static gimple_seq -lower_cleanup (struct leh_state *state, gimple tp) +lower_cleanup (struct leh_state *state, gimple_try tp) { struct leh_state this_state = *state; eh_region this_region = NULL; @@ -2052,36 +2055,39 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi) break; case GIMPLE_TRY: - if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY) - replace = lower_try_finally (state, stmt); - else - { - x = gimple_seq_first_stmt (gimple_try_cleanup (stmt)); - if (!x) - { - replace = gimple_try_eval (stmt); - lower_eh_constructs_1 (state, &replace); - } - else - switch (gimple_code (x)) + { + gimple_try try_stmt = as_a <gimple_try> (stmt); + if (gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY) + replace = lower_try_finally (state, try_stmt); + else + { + x = gimple_seq_first_stmt (gimple_try_cleanup (try_stmt)); + if (!x) { + replace = gimple_try_eval (try_stmt); + lower_eh_constructs_1 (state, &replace); + } + else + switch (gimple_code (x)) + { case GIMPLE_CATCH: - replace = lower_catch (state, stmt); - break; + replace = lower_catch (state, try_stmt); + break; case GIMPLE_EH_FILTER: - replace = lower_eh_filter (state, stmt); - break; + replace = lower_eh_filter (state, try_stmt); + break; case GIMPLE_EH_MUST_NOT_THROW: - replace = lower_eh_must_not_throw (state, stmt); - break; + replace = lower_eh_must_not_throw (state, try_stmt); + break; case GIMPLE_EH_ELSE: - /* This code is only valid with GIMPLE_TRY_FINALLY. */ - gcc_unreachable (); + /* This code is only valid with GIMPLE_TRY_FINALLY. */ + gcc_unreachable (); default: - replace = lower_cleanup (state, stmt); - break; - } - } + replace = lower_cleanup (state, try_stmt); + break; + } + } + } /* Remove the old stmt and insert the transformed sequence instead. */ -- 1.8.5.3