From c72520421033d2597496ff05c3ccbec8c505d549 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 13 Nov 2025 13:40:27 +0100 Subject: [PATCH] ipa/122663 - fix ICE with stmt removal during IPA modification We currently remove stmts inside of a FOR_EACH_IMM_USE_STMT iteration which can be problematical. The following adjusts purge_all_uses to gather all stmts to remove and remove them in reverse order afterwards which also better deals with debug stmt generation. PR ipa/122663 * ipa-param-manipulation.cc (purge_all_uses): Collect stmts to remove and process that list in reverse. * g++.dg/torture/pr122663.C: New testcase. --- gcc/ipa-param-manipulation.cc | 13 +++++++++++-- gcc/testsuite/g++.dg/torture/pr122663.C | 26 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr122663.C diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 11f843c48d1..96ab125dee1 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -636,6 +636,7 @@ purge_all_uses (tree name, hash_set *killed_ssas) imm_use_iterator imm_iter; gimple *stmt; auto_vec worklist; + auto_vec kill_list; worklist.safe_push (name); while (!worklist.is_empty ()) @@ -664,11 +665,19 @@ purge_all_uses (tree name, hash_set *killed_ssas) if (!killed_ssas->add (lhs)) { worklist.safe_push (lhs); - gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - gsi_remove (&gsi, true); + kill_list.safe_push (stmt); } } } + + /* Remove stmts in reverse and afterwards to properly handle debug stmt + generation and to not interfere with immediate use iteration. */ + while (!kill_list.is_empty ()) + { + stmt = kill_list.pop (); + gimple_stmt_iterator gsi = gsi_for_stmt (stmt); + gsi_remove (&gsi, true); + } } /* Modify actual arguments of a function call in statement currently belonging diff --git a/gcc/testsuite/g++.dg/torture/pr122663.C b/gcc/testsuite/g++.dg/torture/pr122663.C new file mode 100644 index 00000000000..eafcc982a29 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr122663.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-additional-options "-g" } + +int a, b, c; +char bk(int, int); +void bl(int); +inline unsigned d() { + bl(c); + return bk(b, 0); +} +struct e { + template e(bc &); +}; +int g(e) { return 0; } +unsigned h(e k) { return g(k); } +unsigned i(e k) { return h(k); } +inline unsigned j() { + unsigned bh = i(a); + bh += d(); + return bh; +} +void f() { + j(); + j(); + __builtin_unreachable(); +} -- 2.47.3