]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa/122663 - fix ICE with stmt removal during IPA modification
authorRichard Biener <rguenther@suse.de>
Thu, 13 Nov 2025 12:40:27 +0000 (13:40 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 14 Nov 2025 12:05:29 +0000 (13:05 +0100)
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
gcc/testsuite/g++.dg/torture/pr122663.C [new file with mode: 0644]

index 11f843c48d1b6ad62b56cdee68ea346616ca6c90..96ab125dee18888fef2e04e83fe9ebf18df21b5b 100644 (file)
@@ -636,6 +636,7 @@ purge_all_uses (tree name, hash_set <tree> *killed_ssas)
   imm_use_iterator imm_iter;
   gimple *stmt;
   auto_vec <tree, 4> worklist;
+  auto_vec <gimple *, 4> kill_list;
 
   worklist.safe_push (name);
   while (!worklist.is_empty ())
@@ -664,11 +665,19 @@ purge_all_uses (tree name, hash_set <tree> *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 (file)
index 0000000..eafcc98
--- /dev/null
@@ -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 <class bc> 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();
+}