diff options
Diffstat (limited to 'gcc/tree-optimize.c')
-rw-r--r-- | gcc/tree-optimize.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index d13c04f..3e7ca89 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -180,6 +180,25 @@ execute_fixup_cfg (void) FOR_EACH_EDGE (e, ei, bb->succs) e->count = (e->count * count_scale + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE; + + /* If we have a basic block with no successors that does not + end with a control statement or a noreturn call end it with + a call to __builtin_unreachable. This situation can occur + when inlining a noreturn call that does in fact return. */ + if (EDGE_COUNT (bb->succs) == 0) + { + gimple stmt = last_stmt (bb); + if (!stmt + || (!is_ctrl_stmt (stmt) + && (!is_gimple_call (stmt) + || (gimple_call_flags (stmt) & ECF_NORETURN) == 0))) + { + stmt = gimple_build_call + (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0); + gimple_stmt_iterator gsi = gsi_last_bb (bb); + gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); + } + } } if (count_scale != REG_BR_PROB_BASE) compute_function_frequency (); |