]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-109823: Adjust labels in compiler when removing an empty basic block which is...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Mon, 25 Sep 2023 18:25:05 +0000 (19:25 +0100)
committerGitHub <noreply@github.com>
Mon, 25 Sep 2023 18:25:05 +0000 (18:25 +0000)
Lib/test/test_compile.py
Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst [new file with mode: 0644]
Python/flowgraph.c

index d3a5517963c54003a83e37f8cc433bab44650dae..53e3e8f75aa7661e119e21d86e6e8f0253aa1659 100644 (file)
@@ -1272,6 +1272,11 @@ class TestSpecifics(unittest.TestCase):
             else:
                 1 if 1 else 1
 
+    def test_remove_empty_basic_block_with_jump_target_label(self):
+        # See gh-109823
+        def f(x):
+            while x:
+                0 if 1 else 0
 
 @requires_debug_ranges()
 class TestSourcePositions(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst
new file mode 100644 (file)
index 0000000..793c89f
--- /dev/null
@@ -0,0 +1,2 @@
+Fix bug where compiler does not adjust labels when removing an empty basic
+block which is a jump target.
index adfcef33895a538bb469819adf657d8e27c62ed2..9c24264cfbb45910c9695c5bc70a257e8b4084be 100644 (file)
@@ -960,6 +960,7 @@ eliminate_empty_basic_blocks(cfg_builder *g) {
     while(g->g_entryblock && g->g_entryblock->b_iused == 0) {
         g->g_entryblock = g->g_entryblock->b_next;
     }
+    int next_lbl = get_max_label(g->g_entryblock) + 1;
     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
         assert(b->b_iused > 0);
         for (int i = 0; i < b->b_iused; i++) {
@@ -969,7 +970,13 @@ eliminate_empty_basic_blocks(cfg_builder *g) {
                 while (target->b_iused == 0) {
                     target = target->b_next;
                 }
-                instr->i_target = target;
+                if (instr->i_target != target) {
+                    if (!IS_LABEL(target->b_label)) {
+                        target->b_label.id = next_lbl++;
+                    }
+                    instr->i_target = target;
+                    instr->i_oparg = target->b_label.id;
+                }
                 assert(instr->i_target && instr->i_target->b_iused > 0);
             }
         }