]> granicus.if.org Git - python/commitdiff
bpo-37269: Correctly optimise conditionals with constant booleans (GH-14071)
authorPablo Galindo <Pablogsal@gmail.com>
Fri, 14 Jun 2019 05:54:53 +0000 (06:54 +0100)
committerGitHub <noreply@github.com>
Fri, 14 Jun 2019 05:54:53 +0000 (06:54 +0100)
Fix a regression introduced by af8646c8054d0f4180a2013383039b6a472f9698 that was causing code of the form:

if True and False:
   do_something()

to be optimized incorrectly, eliminating the block.

Lib/test/test_peepholer.py
Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst [new file with mode: 0644]
Python/peephole.c

index 860ceeb003e7b3d7bb9b539aefa8f1f74f686da2..5d00240e2595a8c8088ad187f1b15c2ac5181d21 100644 (file)
@@ -414,6 +414,13 @@ class TestTranforms(BytecodeTestCase):
                 pass
         self.assertEqual(count_instr_recursively(forloop, 'BUILD_LIST'), 0)
 
+    def test_condition_with_binop_with_bools(self):
+        def f():
+            if True or False:
+                return 1
+            return 0
+        self.assertEqual(f(), 1)
+
 
 class TestBuglets(unittest.TestCase):
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst
new file mode 100644 (file)
index 0000000..b9b7906
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a bug in the peephole optimizer that was not treating correctly constant
+conditions with binary operators. Patch by Pablo Galindo.
index 6f3e2ed88b2bedc631c62a63ea836287b29ee2a6..d7b1dfc4d9c1419d2b1fbd8d59bdeded5d9b7f56 100644 (file)
@@ -315,6 +315,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
                     fill_nops(codestr, op_start, nexti + 1);
                     cumlc = 0;
                 } else if (is_true == 0) {
+                    if (i > 1 &&
+                        (_Py_OPCODE(codestr[i - 1]) == POP_JUMP_IF_TRUE ||
+                         _Py_OPCODE(codestr[i - 1]) == POP_JUMP_IF_FALSE)) {
+                        break;
+                    }
                     h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT);
                     tgt = find_op(codestr, codelen, h);
                     fill_nops(codestr, op_start, tgt);