http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45854
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2010.10.01 10:38:16 AssignedTo|unassigned at gcc dot |rguenth at gcc dot gnu.org |gnu.org | Target Milestone|--- |4.5.2 Summary|ICE in redirect_eh_edge_1, |[4.5 Regression] ICE in |at tree-eh.c:2131 |redirect_eh_edge_1, at | |tree-eh.c:2131 Ever Confirmed|0 |1 --- Comment #1 from Richard Guenther <rguenth at gcc dot gnu.org> 2010-10-01 10:38:16 UTC --- Confirmed. #1 0x0000000000c55d81 in redirect_eh_edge_1 (edge_in=0x7ffff5b4bb00, new_bb=0x7ffff5b596e8, change_region=0 '\000') at /space/rguenther/src/svn/gcc-4_5-branch/gcc/tree-eh.c:2131 #2 0x0000000000c5bc01 in cleanup_empty_eh_merge_phis (new_bb=0x7ffff5b596e8, old_bb=0x7ffff5b596e8, old_bb_out=0x7ffff5b4bd80, change_region=0 '\000') at /space/rguenther/src/svn/gcc-4_5-branch/gcc/tree-eh.c:3594 #3 0x0000000000c5bfe8 in cleanup_empty_eh_unsplit (bb=0x7ffff5b596e8, e_out=0x7ffff5b4bd80, lp=0x7ffff5b50a78) at /space/rguenther/src/svn/gcc-4_5-branch/gcc/tree-eh.c:3673 #4 0x0000000000c5c1de in cleanup_empty_eh (lp=0x7ffff5b50a78) at /space/rguenther/src/svn/gcc-4_5-branch/gcc/tree-eh.c:3723 #5 0x0000000000c5c523 in cleanup_all_empty_eh () at /space/rguenther/src/svn/gcc-4_5-branch/gcc/tree-eh.c:3825 #6 0x0000000000c5c5b3 in execute_cleanup_eh () at /space/rguenther/src/svn/gcc-4_5-branch/gcc/tree-eh.c:3854 #7 0x0000000000b15380 in execute_one_pass (pass=0x18ca7a0) at /space/rguenther/src/svn/gcc-4_5-branch/gcc/passes.c:1568 (gdb) p *pass $1 = {type = GIMPLE_PASS, name = 0x13b7692 "ehcleanup", gate = 0xc5c5ef <gate_cleanup_eh>, execute = 0xc5c579 <execute_cleanup_eh>, sub = 0x0, next = 0x18c90e0, static_pass_number = 41, tv_id = TV_TREE_EH, properties_required = 2, properties_provided = 0, properties_destroyed = 0, todo_flags_start = 524288, todo_flags_finish = 1} (gdb) call debug_function (cfun->decl, 1<<19 | 1<<5) <anonymous struct>::._0() (struct ._0 * const this) Eh tree: 1 cleanup { struct Y * D.2249; struct S * D.2248; struct X D.2247; # BLOCK 2 # PRED: ENTRY (fallthru,exec) D.2247 = {}; D.2248_2 = &this_1(D)->s; S::S (D.2248_2, D.2247); D.2249_3 = &this_1(D)->y; [LP 1] Y::Y (D.2249_3); # SUCC: 5 (eh,exec) 3 (fallthru,exec) # BLOCK 3 # PRED: 2 (fallthru,exec) return; # SUCC: EXIT # BLOCK 4 # PRED: <L0>: # SUCC: # BLOCK 5 freq:10000 # PRED: 5 [100.0%] (fallthru,dfs_back) 2 (eh,exec) <L1>: goto <bb 5> (<L1>); # SUCC: 5 [100.0%] (fallthru,dfs_back) } (gdb) p edge_in->dest->index $4 = 5 (gdb) p new_bb->index $5 = 5 so we're trying to re-direct an EH edge from BB 5 to BB 5 ... And the following fixes it. Index: gcc/tree-eh.c =================================================================== --- gcc/tree-eh.c (revision 164873) +++ gcc/tree-eh.c (working copy) @@ -3720,7 +3720,13 @@ cleanup_empty_eh (eh_landing_pad lp) /* If the block is totally empty, look for more unsplitting cases. */ if (gsi_end_p (gsi)) - return cleanup_empty_eh_unsplit (bb, e_out, lp); + { + /* For the degenerate case of an infinite loop bail out. */ + if (e_out->dest == bb) + return false; + + return cleanup_empty_eh_unsplit (bb, e_out, lp); + } /* The block should consist only of a single RESX statement. */ resx = gsi_stmt (gsi);