Hi, the testcase reproduce ICE in a very corner case of inlining. What happens is 1) early inlining is tricked to produce very complex self recursive callgraph graph by somewhat bogus inlining of self recursive cycles 2) late inliner decide to continue in the recursive inlining 3) ipa-pure-const detect that the recrusive cycle is non-throwing. This is not detected by local-pure-const because at that time the inline cycle is still indirect recursion we do not handle there 4) in inline-transform we notice the recursive inlining and save function body for later reuse 5) during duplication we get rid of the now dead EH edge from call to EH receiver because of ipa-pure-const change on functio ndeclaration. 6) after duplication we must delete unreachable blocks to build dominators and update SSA. This gets rid of the dead basic block containing the inlined recursive call. This means updating all the clones by removing calls and if the call is inlined also the inline clones representing the duplication. Because inlining is recursive, we end up removing the inlined function itself, but we can not since we are just duplicating it. So we postpone this for later. 7) we ice in verify_cgraph clone because step 6) did not removed the dead call.
This patch fixes it. The bug existed in a tree quite forever, but it leads only to enable-checking ICE and nothing else (the extra edge will be removed shortly after the verify_cgraph_node call), so I think it needs no backporting. Bootstrapped/regtested x86_64-linux, will commit it shortly. Honza PR tree-optimization/r55789 * cgraphclones.c (cgraph_remove_node_and_inline_clones): Remove the dead call anyway. * g++.dg/torture/pr55789.C: New testcase. Index: testsuite/g++.dg/torture/pr55789.C =================================================================== *** testsuite/g++.dg/torture/pr55789.C (revision 0) --- testsuite/g++.dg/torture/pr55789.C (revision 0) *************** *** 0 **** --- 1,30 ---- + /* { dg-do compile } */ + /* { dg-options "-fno-guess-branch-probability -fno-tree-forwprop --param max-early-inliner-iterations=10 --param=early-inlining-insns=176" } */ + + template < typename T > struct intrusive_ptr + { + ~intrusive_ptr () + { + delete px; + } + T *px; + }; + + struct section_info + { + intrusive_ptr < section_info > parent; + }; + + struct file_info + { + intrusive_ptr < file_info > parent; + intrusive_ptr < section_info > switched_section; + }; + + + void + start_file (void) + { + intrusive_ptr < file_info > parent; + } + Index: cgraphclones.c =================================================================== *** cgraphclones.c (revision 195370) --- cgraphclones.c (working copy) *************** cgraph_remove_node_and_inline_clones (st *** 570,576 **** bool found = false; if (node == forbidden_node) ! return true; for (e = node->callees; e; e = next) { next = e->next_callee; --- 570,579 ---- bool found = false; if (node == forbidden_node) ! { ! cgraph_remove_edge (node->callers); ! return true; ! } for (e = node->callees; e; e = next) { next = e->next_callee;