]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-120367: fix removal of redundant NOPs and jumps after reordering hot-cold...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 17 Jun 2024 15:07:20 +0000 (17:07 +0200)
committerGitHub <noreply@github.com>
Mon, 17 Jun 2024 15:07:20 +0000 (16:07 +0100)
gh-120367: fix removal of redundant NOPs and jumps after reordering hot-cold blocks (GH-120425)
(cherry picked from commit 21866c8ed296524f0ca175c0f55b43744c2b30df)

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
Lib/test/test_compile.py
Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst [new file with mode: 0644]
Python/flowgraph.c

index 410cdce692df374774c8d851cafcc869bb2d4613..417bc8c6a770d8239374a16e1eb36ec9f437b849 100644 (file)
@@ -502,6 +502,33 @@ class TestSpecifics(unittest.TestCase):
         with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"):
             compile(ast.fix_missing_locations(m), "<file>", "exec")
 
+    def test_compile_redundant_jumps_and_nops_after_moving_cold_blocks(self):
+        # See gh-120367
+        code=textwrap.dedent("""
+            try:
+                pass
+            except:
+                pass
+            else:
+                match name_2:
+                    case b'':
+                        pass
+            finally:
+                something
+            """)
+
+        tree = ast.parse(code)
+
+        # make all instructions locations the same to create redundancies
+        for node in ast.walk(tree):
+            if hasattr(node,"lineno"):
+                 del node.lineno
+                 del node.end_lineno
+                 del node.col_offset
+                 del node.end_col_offset
+
+        compile(ast.fix_missing_locations(tree), "<file>", "exec")
+
     def test_compile_ast(self):
         fname = __file__
         if fname.lower().endswith('pyc'):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-12-18-50-29.gh-issue-120367.LmXx2y.rst
new file mode 100644 (file)
index 0000000..2d7212a
--- /dev/null
@@ -0,0 +1,2 @@
+Fix crash in compiler on code with redundant NOPs and JUMPs which show up
+after exception handlers are moved to the end of the code.
index b43cb6b81f3322134a24bc7bb9421c40e946b4a9..17b62b62a85a6a40c8bda13529a19a3325206454 100644 (file)
@@ -1829,6 +1829,22 @@ error:
 
 static int resolve_line_numbers(cfg_builder *g, int firstlineno);
 
+static int
+remove_redundant_nops_and_jumps(cfg_builder *g)
+{
+    int removed_nops, removed_jumps;
+    do {
+        /* Convergence is guaranteed because the number of
+         * redundant jumps and nops only decreases.
+         */
+        removed_nops = remove_redundant_nops(g);
+        RETURN_IF_ERROR(removed_nops);
+        removed_jumps = remove_redundant_jumps(g);
+        RETURN_IF_ERROR(removed_jumps);
+    } while(removed_nops + removed_jumps > 0);
+    return SUCCESS;
+}
+
 /* Perform optimizations on a control flow graph.
    The consts object should still be in list form to allow new constants
    to be appended.
@@ -1850,17 +1866,7 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache, int firstl
     }
     RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock));
     RETURN_IF_ERROR(remove_unreachable(g->g_entryblock));
-
-    int removed_nops, removed_jumps;
-    do {
-        /* Convergence is guaranteed because the number of
-         * redundant jumps and nops only decreases.
-         */
-        removed_nops = remove_redundant_nops(g);
-        RETURN_IF_ERROR(removed_nops);
-        removed_jumps = remove_redundant_jumps(g);
-        RETURN_IF_ERROR(removed_jumps);
-    } while(removed_nops + removed_jumps > 0);
+    RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g));
     assert(no_redundant_jumps(g));
     return SUCCESS;
 }
@@ -2330,7 +2336,7 @@ push_cold_blocks_to_end(cfg_builder *g) {
     b->b_next = cold_blocks;
 
     if (cold_blocks != NULL) {
-        RETURN_IF_ERROR(remove_redundant_jumps(g));
+        RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g));
     }
     return SUCCESS;
 }