@@ -710,7 +710,7 @@ void zend_stop_lexing(void)
710710}
711711
712712static inline void zend_begin_loop (
713- uint8_t free_opcode , const znode * loop_var , bool is_switch ) /* {{{ */
713+ uint8_t free_opcode , const znode * loop_var , zend_brk_ctrl_kind kind ) /* {{{ */
714714{
715715 zend_brk_cont_element * brk_cont_element ;
716716 int parent = CG (context ).current_brk_cont ;
@@ -719,7 +719,7 @@ static inline void zend_begin_loop(
719719 CG (context ).current_brk_cont = CG (context ).last_brk_cont ;
720720 brk_cont_element = get_next_brk_cont_element ();
721721 brk_cont_element -> parent = parent ;
722- brk_cont_element -> is_switch = is_switch ;
722+ brk_cont_element -> kind = kind ;
723723
724724 uint32_t start = get_next_op_number ();
725725 info .opcode_start = start ;
@@ -5821,16 +5821,17 @@ static void zend_compile_break_continue(zend_ast *ast) /* {{{ */
58215821 }
58225822 }
58235823
5824- if ( ast -> kind == ZEND_AST_CONTINUE ) {
5825- int d , cur = CG ( context ). current_brk_cont ;
5826- for ( d = depth - 1 ; d > 0 ; d -- ) {
5827- cur = CG ( context ). brk_cont_array [ cur ]. parent ;
5828- ZEND_ASSERT ( cur != -1 );
5829- }
5824+ int d , cur = CG ( context ). current_brk_cont ;
5825+ for ( d = depth - 1 ; d > 0 ; d -- ) {
5826+ cur = CG ( context ). brk_cont_array [ cur ]. parent ;
5827+ ZEND_ASSERT ( cur != -1 ) ;
5828+ }
5829+ zend_brk_cont_element * current_brk_ctrl = & CG ( context ). brk_cont_array [ cur ];
58305830
5831- if (CG (context ).brk_cont_array [cur ].is_switch ) {
5831+ if (ast -> kind == ZEND_AST_CONTINUE ) {
5832+ if (current_brk_ctrl -> kind == ZEND_BRK_CTRL_KIND_SWITCH_MATCH_STMT ) {
58325833 if (depth == 1 ) {
5833- if (CG ( context ). brk_cont_array [ cur ]. parent == -1 ) {
5834+ if (current_brk_ctrl -> parent == -1 ) {
58345835 zend_error (E_WARNING ,
58355836 "\"continue\" targeting switch is equivalent to \"break\"" );
58365837 } else {
@@ -5840,7 +5841,7 @@ static void zend_compile_break_continue(zend_ast *ast) /* {{{ */
58405841 depth + 1 );
58415842 }
58425843 } else {
5843- if (CG ( context ). brk_cont_array [ cur ]. parent == -1 ) {
5844+ if (current_brk_ctrl -> parent == -1 ) {
58445845 zend_error (E_WARNING ,
58455846 "\"continue " ZEND_LONG_FMT "\" targeting switch is equivalent to \"break " ZEND_LONG_FMT "\"" ,
58465847 depth , depth );
@@ -5853,6 +5854,10 @@ static void zend_compile_break_continue(zend_ast *ast) /* {{{ */
58535854 }
58545855 }
58555856 }
5857+ if (current_brk_ctrl -> kind == ZEND_BRK_CTRL_KIND_MATCH_EXPR ) {
5858+ zend_error_noreturn (E_COMPILE_ERROR , "%s must not target match expression whose result is used" ,
5859+ ast -> kind == ZEND_AST_BREAK ? "break" : "continue" );
5860+ }
58565861
58575862 opline = zend_emit_op (NULL , ast -> kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT , NULL , NULL );
58585863 opline -> op1 .num = CG (context ).current_brk_cont ;
@@ -5966,7 +5971,7 @@ static void zend_compile_while(zend_ast *ast) /* {{{ */
59665971
59675972 opnum_jmp = zend_emit_jump (0 );
59685973
5969- zend_begin_loop (ZEND_NOP , NULL , 0 );
5974+ zend_begin_loop (ZEND_NOP , NULL , ZEND_BRK_CTRL_KIND_LOOP );
59705975
59715976 opnum_start = get_next_op_number ();
59725977 zend_compile_stmt (stmt_ast );
@@ -5989,7 +5994,7 @@ static void zend_compile_do_while(zend_ast *ast) /* {{{ */
59895994 znode cond_node ;
59905995 uint32_t opnum_start , opnum_cond ;
59915996
5992- zend_begin_loop (ZEND_NOP , NULL , 0 );
5997+ zend_begin_loop (ZEND_NOP , NULL , ZEND_BRK_CTRL_KIND_LOOP );
59935998
59945999 opnum_start = get_next_op_number ();
59956000 zend_compile_stmt (stmt_ast );
@@ -6040,7 +6045,7 @@ static void zend_compile_for(zend_ast *ast) /* {{{ */
60406045
60416046 opnum_jmp = zend_emit_jump (0 );
60426047
6043- zend_begin_loop (ZEND_NOP , NULL , 0 );
6048+ zend_begin_loop (ZEND_NOP , NULL , ZEND_BRK_CTRL_KIND_LOOP );
60446049
60456050 opnum_start = get_next_op_number ();
60466051 zend_compile_stmt (stmt_ast );
@@ -6102,7 +6107,7 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
61026107 opnum_reset = get_next_op_number ();
61036108 opline = zend_emit_op (& reset_node , by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R , & expr_node , NULL );
61046109
6105- zend_begin_loop (ZEND_FE_FREE , & reset_node , 0 );
6110+ zend_begin_loop (ZEND_FE_FREE , & reset_node , ZEND_BRK_CTRL_KIND_LOOP );
61066111
61076112 opnum_fetch = get_next_op_number ();
61086113 opline = zend_emit_op (NULL , by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R , & reset_node , NULL );
@@ -6275,7 +6280,7 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */
62756280
62766281 zend_compile_expr (& expr_node , expr_ast );
62776282
6278- zend_begin_loop (ZEND_FREE , & expr_node , 1 );
6283+ zend_begin_loop (ZEND_FREE , & expr_node , ZEND_BRK_CTRL_KIND_SWITCH_MATCH_STMT );
62796284
62806285 case_node .op_type = IS_TMP_VAR ;
62816286 case_node .u .op .var = get_temporary_variable ();
@@ -6460,7 +6465,7 @@ static void zend_compile_match(znode *result, zend_ast *ast)
64606465 zend_stack_push (& CG (loop_var_stack ), & info );
64616466 }
64626467
6463- zend_begin_loop (ZEND_FREE , & expr_node , /* is_switch */ true );
6468+ zend_begin_loop (ZEND_FREE , & expr_node , result ? ZEND_BRK_CTRL_KIND_MATCH_EXPR : ZEND_BRK_CTRL_KIND_SWITCH_MATCH_STMT );
64646469
64656470 znode case_node ;
64666471 case_node .op_type = IS_TMP_VAR ;
0 commit comments