bpo-1875: Raise SyntaxError in invalid blocks that will be optimised … · python/cpython@af8646c (original) (raw)

File tree

4 files changed

lines changed

4 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -696,6 +696,20 @@ def error2():
696 696 def test_break_outside_loop(self):
697 697 self._check_error("break", "outside loop")
698 698
699 +def test_yield_outside_function(self):
700 +self._check_error("if 0: yield", "outside function")
701 +self._check_error("class C:\n if 0: yield", "outside function")
702 +
703 +def test_return_outside_function(self):
704 +self._check_error("if 0: return", "outside function")
705 +self._check_error("class C:\n if 0: return", "outside function")
706 +
707 +def test_break_outside_loop(self):
708 +self._check_error("if 0: break", "outside loop")
709 +
710 +def test_continue_outside_loop(self):
711 +self._check_error("if 0: continue", "not properly in loop")
712 +
699 713 def test_unexpected_indent(self):
700 714 self._check_error("foo()\n bar()\n", "unexpected indent",
701 715 subclass=IndentationError)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 +A :exc:`SyntaxError` is now raised if a code blocks that will be optimized
2 +away (e.g. if conditions that are always false) contains syntax errors.
3 +Patch by Pablo Galindo.
Original file line number Diff line number Diff line change
@@ -2546,13 +2546,12 @@ compiler_if(struct compiler *c, stmt_ty s)
2546 2546 return 0;
2547 2547
2548 2548 constant = expr_constant(s->v.If.test);
2549 -/* constant = 0: "if 0"
2549 +/* constant = 0: "if 0" Leave the optimizations to
2550 + * the pephole optimizer to check for syntax errors
2551 + * in the block.
2550 2552 * constant = 1: "if 1", "if 2", ...
2551 2553 * constant = -1: rest */
2552 -if (constant == 0) {
2553 -if (s->v.If.orelse)
2554 -VISIT_SEQ(c, stmt, s->v.If.orelse);
2555 - } else if (constant == 1) {
2554 +if (constant == 1) {
2556 2555 VISIT_SEQ(c, stmt, s->v.If.body);
2557 2556 } else {
2558 2557 if (asdl_seq_LEN(s->v.If.orelse)) {
Original file line number Diff line number Diff line change
@@ -302,11 +302,19 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
302 302 case LOAD_CONST:
303 303 cumlc = lastlc + 1;
304 304 if (nextop != POP_JUMP_IF_FALSE |
305 - !ISBASICBLOCK(blocks, op_start, i + 1) |
306 - !PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i))))
305 + !ISBASICBLOCK(blocks, op_start, i + 1)) {
307 306 break;
308 -fill_nops(codestr, op_start, nexti + 1);
309 -cumlc = 0;
307 + }
308 +PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i));
309 +int is_true = PyObject_IsTrue(cnt);
310 +if (is_true == 1) {
311 +fill_nops(codestr, op_start, nexti + 1);
312 +cumlc = 0;
313 + } else if (is_true == 0) {
314 +h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT);
315 +tgt = find_op(codestr, codelen, h);
316 +fill_nops(codestr, op_start, tgt);
317 + }
310 318 break;
311 319
312 320 /* Try to fold tuples of constants.