diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 942c480a7c3..c2ce1f73fec 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -78,14 +78,16 @@ assert(0 && ($a = function &(array &$a, X $b = null) use ($c,&$d) : X { return 9; } L0: - switch ($x) { - case 4: break; - case 5: continue; - case 6: break 2; - case 7: continue 2; - case 8: goto L0; - default: return; - } + do { + switch ($x) { + case 4: break; + case 5: continue; + case 6: break 2; + case 7: continue 2; + case 8: goto L0; + default: return; + } + } while (0); } } } @@ -222,20 +224,22 @@ Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null) use($c, return 9; } L0: - switch ($x) { - case 4: - break; - case 5: - continue; - case 6: - break 2; - case 7: - continue 2; - case 8: - goto L0; - default: - return; - } + do { + switch ($x) { + case 4: + break; + case 5: + continue; + case 6: + break 2; + case 7: + continue 2; + case 8: + goto L0; + default: + return; + } + } while (0); } } diff --git a/Zend/tests/try_finally_011.phpt b/Zend/tests/try_finally_011.phpt index 7aa3f35feeb..8a9dc62ca4f 100644 --- a/Zend/tests/try_finally_011.phpt +++ b/Zend/tests/try_finally_011.phpt @@ -12,4 +12,4 @@ function foo () { foo(); ?> --EXPECTF-- -Fatal error: Cannot break/continue 1 level in %stry_finally_011.php on line %d +Fatal error: 'break' not in the 'loop' or 'switch' context in %stry_finally_011.php on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f77d603d0d0..298fa8c58f1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3495,6 +3495,22 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ ZVAL_LONG(&depth_node.u.constant, 1); } + if (CG(context).current_brk_cont == -1) { + zend_error_noreturn(E_COMPILE_ERROR, "'%s' not in the 'loop' or 'switch' context", + ast->kind == ZEND_AST_BREAK ? "break" : "continue"); + } else { + int array_offset = CG(context).current_brk_cont; + zend_long nest_level = Z_LVAL(depth_node.u.constant); + + do { + if (array_offset == -1) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s", + ast->kind == ZEND_AST_BREAK ? "break" : "continue", + Z_LVAL(depth_node.u.constant), (Z_LVAL(depth_node.u.constant) == 1) ? "" : "s"); + } + array_offset = CG(active_op_array)->brk_cont_array[array_offset].parent; + } while (--nest_level > 0); + } opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, NULL, &depth_node); opline->op1.opline_num = CG(context).current_brk_cont; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 7b7b4b528be..6c0d707c74c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1731,9 +1731,7 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of zend_brk_cont_element *jmp_to; do { - if (array_offset==-1) { - zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s"); - } + ZEND_ASSERT(array_offset != -1); jmp_to = &op_array->brk_cont_array[array_offset]; if (nest_levels>1) { zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];