mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Handle incorrect break/continue statements at compile-time
This commit is contained in:
parent
4fd93a4da6
commit
8c031a3f95
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user