summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/assert/expect_015.phpt48
-rw-r--r--Zend/tests/try_finally_011.phpt2
-rw-r--r--Zend/zend_compile.c16
-rw-r--r--Zend/zend_execute.c4
4 files changed, 44 insertions, 26 deletions
diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt
index 942c480a7c..c2ce1f73fe 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 7aa3f35fee..8a9dc62ca4 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 f77d603d0d..298fa8c58f 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 7b7b4b528b..6c0d707c74 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];