From patchwork Mon Jun 21 16:03:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix bug with noreturn call Date: Mon, 21 Jun 2010 06:03:48 -0000 From: Eric Botcazou X-Patchwork-Id: 56330 Message-Id: <201006211803.49205.ebotcazou@adacore.com> To: gcc-patches@gcc.gnu.org Hi, with our 4.5-based compiler, ACATS cxh1001 ICEs at -O2 -flto because of a dangling GIMPLE_CALL statement on the MODIFIED_NORETURN_CALLS list: the statement is replaced in cgraph_redirect_edge_call_stmt_to_callee but it nevertheless remains on the list. Moveover the new statement doesn't inherit the noreturn property. Fixed by clearing the BB. The patch also removes a superfluous call to maybe_clean_or_replace_eh_stmt (gsi_replace already calls it) and makes sure that all the flags are copied in gimple_call_copy_skip_args. Tested on x86_64-suse-linux. OK for mainline (and 4.5 branch)? 2010-06-21 Eric Botcazou * cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Chain the new statement only if necessary and clear its BB. Remove superfluous call to maybe_clean_or_replace_eh_stmt. * gimple.c (gimple_call_copy_skip_args): Use gimple_call_copy_flags to copy the flags. Index: cgraphunit.c =================================================================== --- cgraphunit.c (revision 161008) +++ cgraphunit.c (working copy) @@ -2345,7 +2345,6 @@ cgraph_redirect_edge_call_stmt_to_callee { tree decl = gimple_call_fndecl (e->call_stmt); gimple new_stmt; - gimple_stmt_iterator gsi; #ifdef ENABLE_CHECKING struct cgraph_node *node; #endif @@ -2383,13 +2382,15 @@ cgraph_redirect_edge_call_stmt_to_callee SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; gimple_call_set_fndecl (new_stmt, e->callee->decl); - gsi = gsi_for_stmt (e->call_stmt); - gsi_replace (&gsi, new_stmt, true); + if (new_stmt != e->call_stmt) + { + gimple_stmt_iterator gsi = gsi_for_stmt (e->call_stmt); + gsi_replace (&gsi, new_stmt, true); + /* Clear its BB in case it is on the MODIFIED_NORETURN_CALLS list. */ + gimple_set_bb (e->call_stmt, NULL); + } update_stmt (new_stmt); - /* Update EH information too, just in case. */ - maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt); - cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt); if (cgraph_dump_file) Index: gimple.c =================================================================== --- gimple.c (revision 161008) +++ gimple.c (working copy) @@ -3085,14 +3085,8 @@ gimple_call_copy_skip_args (gimple stmt, gimple_set_block (new_stmt, gimple_block (stmt)); if (gimple_has_location (stmt)) gimple_set_location (new_stmt, gimple_location (stmt)); - - /* Carry all the flags to the new GIMPLE_CALL. */ + gimple_call_copy_flags (new_stmt, stmt); gimple_call_set_chain (new_stmt, gimple_call_chain (stmt)); - gimple_call_set_tail (new_stmt, gimple_call_tail_p (stmt)); - gimple_call_set_cannot_inline (new_stmt, gimple_call_cannot_inline_p (stmt)); - gimple_call_set_return_slot_opt (new_stmt, gimple_call_return_slot_opt_p (stmt)); - gimple_call_set_from_thunk (new_stmt, gimple_call_from_thunk_p (stmt)); - gimple_call_set_va_arg_pack (new_stmt, gimple_call_va_arg_pack_p (stmt)); gimple_set_modified (new_stmt, true);