]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-1875: Raise SyntaxError in invalid blocks that will be optimised away (GH-13332)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 17 May 2019 10:59:48 +0000 (03:59 -0700)
committerGitHub <noreply@github.com>
Fri, 17 May 2019 10:59:48 +0000 (03:59 -0700)
Move the check for dead conditionals (if 0) to the peephole optimizer
and make sure that the code block is still compiled to report any
existing syntax errors within.
(cherry picked from commit af8646c8054d0f4180a2013383039b6a472f9698)

Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Lib/test/test_syntax.py
Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst [new file with mode: 0644]
Python/compile.c
Python/peephole.c

index 2b96a94401a87d7451ebaf128da38bfefb6397a3..4918e5c4c4284e076a3b55e3fbdcbf17cd0bd052 100644 (file)
@@ -650,6 +650,20 @@ class SyntaxTestCase(unittest.TestCase):
     def test_break_outside_loop(self):
         self._check_error("break", "outside loop")
 
+    def test_yield_outside_function(self):
+        self._check_error("if 0: yield",               "outside function")
+        self._check_error("class C:\n    if 0: yield", "outside function")
+
+    def test_return_outside_function(self):
+        self._check_error("if 0: return",               "outside function")
+        self._check_error("class C:\n    if 0: return", "outside function")
+
+    def test_break_outside_loop(self):
+        self._check_error("if 0: break",                "outside loop")
+
+    def test_continue_outside_loop(self):
+        self._check_error("if 0: continue",     "not properly in loop")
+
     def test_unexpected_indent(self):
         self._check_error("foo()\n bar()\n", "unexpected indent",
                           subclass=IndentationError)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst
new file mode 100644 (file)
index 0000000..8f095ed
--- /dev/null
@@ -0,0 +1,3 @@
+A :exc:`SyntaxError` is now raised if a code blocks that will be optimized
+away (e.g. if conditions that are always false) contains syntax errors.
+Patch by Pablo Galindo.
index 5688ef8479c0de3e1872b3b92b08adbd6c636c06..d2729d4c6ca37839570f2c9140f6511141be1717 100644 (file)
@@ -2301,13 +2301,12 @@ compiler_if(struct compiler *c, stmt_ty s)
         return 0;
 
     constant = expr_constant(s->v.If.test);
-    /* constant = 0: "if 0"
+    /* constant = 0: "if 0" Leave the optimizations to
+     * the pephole optimizer to check for syntax errors
+     * in the block.
      * constant = 1: "if 1", "if 2", ...
      * constant = -1: rest */
-    if (constant == 0) {
-        if (s->v.If.orelse)
-            VISIT_SEQ(c, stmt, s->v.If.orelse);
-    } else if (constant == 1) {
+    if (constant == 1) {
         VISIT_SEQ(c, stmt, s->v.If.body);
     } else {
         if (asdl_seq_LEN(s->v.If.orelse)) {
index 95b3dbb6bf519292344f39c200847165bd821241..1ae62fa39a2758d47e9fafe8580d5d1b78d887e9 100644 (file)
@@ -304,11 +304,19 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
             case LOAD_CONST:
                 cumlc = lastlc + 1;
                 if (nextop != POP_JUMP_IF_FALSE  ||
-                    !ISBASICBLOCK(blocks, op_start, i + 1)  ||
-                    !PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i))))
+                    !ISBASICBLOCK(blocks, op_start, i + 1)) {
                     break;
-                fill_nops(codestr, op_start, nexti + 1);
-                cumlc = 0;
+                }
+                PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i));
+                int is_true = PyObject_IsTrue(cnt);
+                if (is_true == 1) {
+                    fill_nops(codestr, op_start, nexti + 1);
+                    cumlc = 0;
+                } else if (is_true == 0) {
+                    h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT);
+                    tgt = find_op(codestr, codelen, h);
+                    fill_nops(codestr, op_start, tgt);
+                }
                 break;
 
                 /* Try to fold tuples of constants.