]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-113054: Compiler no longer replaces a redundant jump with no line number by a...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Tue, 19 Dec 2023 11:04:44 +0000 (11:04 +0000)
committerGitHub <noreply@github.com>
Tue, 19 Dec 2023 11:04:44 +0000 (11:04 +0000)
Lib/test/test_compile.py
Misc/NEWS.d/next/Core and Builtins/2023-12-14-20-08-35.gh-issue-113054.e20CtM.rst [new file with mode: 0644]
Python/flowgraph.c

index f681d125db7d7a1bb98cdaf6fde3f89e42fa6cff..906e16cc9437fb37029a21f509132ec2a44ccec5 100644 (file)
@@ -444,6 +444,10 @@ class TestSpecifics(unittest.TestCase):
         self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames)
         self.assertIn("__package__", A.f.__code__.co_varnames)
 
+    def test_condition_expression_with_dead_blocks_compiles(self):
+        # See gh-113054
+        compile('if (5 if 5 else T): 0', '<eval>', 'exec')
+
     def test_compile_invalid_namedexpr(self):
         # gh-109351
         m = ast.Module(
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-14-20-08-35.gh-issue-113054.e20CtM.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-14-20-08-35.gh-issue-113054.e20CtM.rst
new file mode 100644 (file)
index 0000000..d0729f9
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed bug where a redundant NOP is not removed, causing an assertion to fail
+in the compiler in debug mode.
index fe632082d5a66c92e3386b65719a169f755b7bd9..d2e3a7ae441c7fcec4e5c7b8b68566cd44d8cef4 100644 (file)
@@ -1110,7 +1110,10 @@ remove_redundant_jumps(cfg_builder *g) {
      * of that jump. If it is, then the jump instruction is redundant and
      * can be deleted.
      */
+
     assert(no_empty_basic_blocks(g));
+
+    bool remove_empty_blocks = false;
     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
         cfg_instr *last = basicblock_last_instr(b);
         assert(last != NULL);
@@ -1122,10 +1125,22 @@ remove_redundant_jumps(cfg_builder *g) {
             }
             if (last->i_target == b->b_next) {
                 assert(b->b_next->b_iused);
-                INSTR_SET_OP0(last, NOP);
+                if (last->i_loc.lineno == NO_LOCATION.lineno) {
+                    b->b_iused--;
+                    if (b->b_iused == 0) {
+                        remove_empty_blocks = true;
+                    }
+                }
+                else {
+                    INSTR_SET_OP0(last, NOP);
+                }
             }
         }
     }
+    if (remove_empty_blocks) {
+        eliminate_empty_basic_blocks(g);
+    }
+    assert(no_empty_basic_blocks(g));
     return SUCCESS;
 }