]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Deal with prior EH/abormal cleanup when fixing up noreturn calls
authorRichard Biener <rguenther@suse.de>
Wed, 10 Sep 2025 15:14:07 +0000 (17:14 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 11 Sep 2025 09:12:13 +0000 (11:12 +0200)
When a dead EH or abnormal edge makes a call queued for noreturn fixup
unreachable, just skip processing it.

PR tree-optimization/121870
* tree-ssa-propagate.cc
(substitute_and_fold_engine::substitute_and_fold): Skip
removed stmts from noreturn fixup.

* g++.dg/torture/pr121870.C: New testcase.

gcc/testsuite/g++.dg/torture/pr121870.C [new file with mode: 0644]
gcc/tree-ssa-propagate.cc

diff --git a/gcc/testsuite/g++.dg/torture/pr121870.C b/gcc/testsuite/g++.dg/torture/pr121870.C
new file mode 100644 (file)
index 0000000..8f4e7ab
--- /dev/null
@@ -0,0 +1,20 @@
+__attribute__((noreturn)) void f1(void)
+{
+    while(true) {}
+}
+static void (*fptr)(void) = f1;
+struct s1
+{
+    ~s1() {
+        fptr();
+    }
+    void DoInner() {
+        fptr();
+    }
+};
+
+void f()
+{
+    s1 xxx;
+    xxx.DoInner();
+}
index ec2068948215a295bd1c86108cec5e23b4b53557..872f881b644cd67c01f98e0f312717684b6ad17b 100644 (file)
@@ -1019,6 +1019,8 @@ substitute_and_fold_engine::substitute_and_fold (basic_block block)
   while (!walker.stmts_to_fixup.is_empty ())
     {
       gimple *stmt = walker.stmts_to_fixup.pop ();
+      if (!gimple_bb (stmt))
+       continue;
       if (dump_file && dump_flags & TDF_DETAILS)
        {
          fprintf (dump_file, "Fixing up noreturn call ");