diff options
author | Richard Henderson <rth@redhat.com> | 2009-09-25 13:49:08 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2009-09-25 13:49:08 -0700 |
commit | 072c87d17058df5073c7cb7e9e46809b7c5c0515 (patch) | |
tree | dfe8ca0c39b739d86e6c80e55f635db2121a5c56 /gcc/tree-eh.c | |
parent | f1a036e46fa3ae4831604357a78b4f57af5133da (diff) | |
download | gcc-072c87d17058df5073c7cb7e9e46809b7c5c0515.zip gcc-072c87d17058df5073c7cb7e9e46809b7c5c0515.tar.gz gcc-072c87d17058df5073c7cb7e9e46809b7c5c0515.tar.bz2 |
re PR middle-end/41469 (-fexceptions ICE in expand_gimple_stmt_1, at cfgexpand.c:1947)
PR middle-end/41469
* tree-eh.c (lower_resx): Resolve RESX with no source region to
__builtin_trap.
(gate_lower_resx): New.
(gate_lower_eh_dispatch): Rename from gate_lower_ehcontrol.
From-SVN: r152185
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r-- | gcc/tree-eh.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index a1aa4b2..70c009d 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2849,10 +2849,26 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map) dst_r = NULL; src_r = get_eh_region_from_number (gimple_resx_region (stmt)); - src_nr = build_int_cst (NULL, src_r->index); gsi = gsi_last_bb (bb); - if (dst_r) + if (src_r == NULL) + { + /* We can wind up with no source region when pass_cleanup_eh shows + that there are no entries into an eh region and deletes it, but + then the block that contains the resx isn't removed. This can + happen without optimization when the switch statement created by + lower_try_finally_switch isn't simplified to remove the eh case. + + Resolve this by expanding the resx node to an abort. */ + + fn = implicit_built_in_decls[BUILT_IN_TRAP]; + x = gimple_build_call (fn, 0); + gsi_insert_before (&gsi, x, GSI_SAME_STMT); + + while (EDGE_COUNT (bb->succs) > 0) + remove_edge (EDGE_SUCC (bb, 0)); + } + else if (dst_r) { /* When we have a destination region, we resolve this by copying the excptr and filter values into place, and changing the edge @@ -2903,6 +2919,7 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map) tree dst_nr = build_int_cst (NULL, dst_r->index); fn = implicit_built_in_decls[BUILT_IN_EH_COPY_VALUES]; + src_nr = build_int_cst (NULL, src_r->index); x = gimple_build_call (fn, 2, dst_nr, src_nr); gsi_insert_before (&gsi, x, GSI_SAME_STMT); @@ -2948,6 +2965,7 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map) case 0: fn = implicit_built_in_decls[BUILT_IN_EH_POINTER]; + src_nr = build_int_cst (NULL, src_r->index); x = gimple_build_call (fn, 1, src_nr); var = create_tmp_var (ptr_type_node, NULL); var = make_ssa_name (var, x); @@ -3000,9 +3018,9 @@ execute_lower_resx (void) } static bool -gate_lower_ehcontrol (void) +gate_lower_resx (void) { - return cfun->eh->region_tree != NULL; + return flag_exceptions != 0; } struct gimple_opt_pass pass_lower_resx = @@ -3010,7 +3028,7 @@ struct gimple_opt_pass pass_lower_resx = { GIMPLE_PASS, "resx", /* name */ - gate_lower_ehcontrol, /* gate */ + gate_lower_resx, /* gate */ execute_lower_resx, /* execute */ NULL, /* sub */ NULL, /* next */ @@ -3175,12 +3193,18 @@ execute_lower_eh_dispatch (void) return any_rewritten ? TODO_update_ssa_only_virtuals : 0; } +static bool +gate_lower_eh_dispatch (void) +{ + return cfun->eh->region_tree != NULL; +} + struct gimple_opt_pass pass_lower_eh_dispatch = { { GIMPLE_PASS, "ehdisp", /* name */ - gate_lower_ehcontrol, /* gate */ + gate_lower_eh_dispatch, /* gate */ execute_lower_eh_dispatch, /* execute */ NULL, /* sub */ NULL, /* next */ |