]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-99708: fix bug where compiler crashes on if expression with an empty body block...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Thu, 24 Nov 2022 10:59:07 +0000 (10:59 +0000)
committerGitHub <noreply@github.com>
Thu, 24 Nov 2022 10:59:07 +0000 (10:59 +0000)
Lib/test/test_compile.py
Misc/NEWS.d/next/Core and Builtins/2022-11-23-18-16-18.gh-issue-99708.7MuaiR.rst [new file with mode: 0644]
Python/compile.c

index 791f20bbad032e74c92cfd5a98c1b0115cd8ebbb..998ce57927f1a9a31c292ac8b8952f0d92171415 100644 (file)
@@ -1146,6 +1146,17 @@ if 1:
                 with self.subTest(source):
                     self.assertEqual(actual_positions, expected_positions)
 
+    def test_if_expression_expression_empty_block(self):
+        # See regression in gh-99708
+        exprs = [
+            "assert (False if 1 else True)",
+            "def f():\n\tif not (False if 1 else True): raise AssertionError",
+            "def f():\n\tif not (False if 1 else True): return 12",
+        ]
+        for expr in exprs:
+            with self.subTest(expr=expr):
+                compile(expr, "<single>", "exec")
+
 
 @requires_debug_ranges()
 class TestSourcePositions(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-23-18-16-18.gh-issue-99708.7MuaiR.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-23-18-16-18.gh-issue-99708.7MuaiR.rst
new file mode 100644 (file)
index 0000000..47f385c
--- /dev/null
@@ -0,0 +1 @@
+Fix bug where compiler crashes on an if expression with an empty body block.
index 366321143a54aa4c5834cfc481f2fa2905c7a1b9..dd8596defb8efe500461bd78ce0b6e6bcfc364c4 100644 (file)
@@ -512,7 +512,7 @@ static int compiler_match(struct compiler *, stmt_ty);
 static int compiler_pattern_subpattern(struct compiler *,
                                        pattern_ty, pattern_context *);
 
-static void remove_redundant_nops(basicblock *bb);
+static int remove_redundant_nops(basicblock *bb);
 
 static PyCodeObject *assemble(struct compiler *, int addNone);
 
@@ -8666,6 +8666,17 @@ static void
 propagate_line_numbers(basicblock *entryblock);
 
 #ifndef NDEBUG
+
+static bool
+no_redundant_nops(cfg_builder *g) {
+    for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
+        if (remove_redundant_nops(b) != 0) {
+            return false;
+        }
+    }
+    return true;
+}
+
 static bool
 no_redundant_jumps(cfg_builder *g) {
     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
@@ -9435,7 +9446,7 @@ inline_small_exit_blocks(basicblock *bb) {
     return 0;
 }
 
-static void
+static int
 remove_redundant_nops(basicblock *bb) {
     /* Remove NOPs when legal to do so. */
     int dest = 0;
@@ -9483,7 +9494,9 @@ remove_redundant_nops(basicblock *bb) {
         prev_lineno = lineno;
     }
     assert(dest <= bb->b_iused);
+    int num_removed = bb->b_iused - dest;
     bb->b_iused = dest;
+    return num_removed;
 }
 
 static int
@@ -9694,10 +9707,11 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache)
             b->b_iused = 0;
        }
     }
-    eliminate_empty_basic_blocks(g);
     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
         remove_redundant_nops(b);
     }
+    eliminate_empty_basic_blocks(g);
+    assert(no_redundant_nops(g));
     if (remove_redundant_jumps(g) < 0) {
         return -1;
     }