diff options
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r-- | gcc/tree-cfgcleanup.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index fc2141f48c1..7f8498a4483 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -559,22 +559,41 @@ fixup_noreturn_call (gimple stmt) { tree op = gimple_call_lhs (stmt); gimple_call_set_lhs (stmt, NULL_TREE); - /* We need to remove SSA name to avoid checking. + + /* We need to remove SSA name to avoid checking errors. All uses are dominated by the noreturn and thus will - be removed afterwards. */ + be removed afterwards. + We proactively remove affected non-PHI statements to avoid + fixup_cfg from trying to update them and crashing. */ if (TREE_CODE (op) == SSA_NAME) { use_operand_p use_p; imm_use_iterator iter; gimple use_stmt; + bitmap_iterator bi; + unsigned int bb_index; + + bitmap blocks = BITMAP_ALLOC (NULL); FOR_EACH_IMM_USE_STMT (use_stmt, iter, op) - FOR_EACH_IMM_USE_ON_STMT (use_p, iter) - SET_USE (use_p, error_mark_node); + { + if (gimple_code (use_stmt) != GIMPLE_PHI) + bitmap_set_bit (blocks, gimple_bb (use_stmt)->index); + else + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, error_mark_node); + } + EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi) + delete_basic_block (BASIC_BLOCK (bb_index)); + BITMAP_FREE (blocks); + release_ssa_name (op); } update_stmt (stmt); changed = true; } + /* Similarly remove VDEF if there is any. */ + else if (gimple_vdef (stmt)) + update_stmt (stmt); return changed; } |