@@ -649,7 +649,8 @@ static void zend_end_live_range(zend_op_array *op_array, uint32_t offset, uint32
649649}
650650/* }}} */
651651
652- static inline void zend_begin_loop (zend_uchar free_opcode , const znode * loop_var ) /* {{{ */
652+ static inline void zend_begin_loop (
653+ zend_uchar free_opcode , const znode * loop_var , zend_bool is_switch ) /* {{{ */
653654{
654655 zend_brk_cont_element * brk_cont_element ;
655656 int parent = CG (context ).current_brk_cont ;
@@ -658,6 +659,7 @@ static inline void zend_begin_loop(zend_uchar free_opcode, const znode *loop_var
658659 CG (context ).current_brk_cont = CG (context ).last_brk_cont ;
659660 brk_cont_element = get_next_brk_cont_element ();
660661 brk_cont_element -> parent = parent ;
662+ brk_cont_element -> is_switch = is_switch ;
661663
662664 if (loop_var && (loop_var -> op_type & (IS_VAR |IS_TMP_VAR ))) {
663665 uint32_t start = get_next_op_number (CG (active_op_array ));
@@ -4585,6 +4587,29 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
45854587 depth , depth == 1 ? "" : "s" );
45864588 }
45874589 }
4590+
4591+ if (ast -> kind == ZEND_AST_CONTINUE ) {
4592+ int d , cur = CG (context ).current_brk_cont ;
4593+ for (d = depth - 1 ; d > 0 ; d -- ) {
4594+ cur = CG (context ).brk_cont_array [cur ].parent ;
4595+ ZEND_ASSERT (cur != -1 );
4596+ }
4597+
4598+ if (CG (context ).brk_cont_array [cur ].is_switch ) {
4599+ if (depth == 1 ) {
4600+ zend_error (E_WARNING ,
4601+ "\"continue\" targeting switch is equivalent to \"break\". " \
4602+ "Did you mean to use \"continue %d\"?" ,
4603+ depth + 1 );
4604+ } else {
4605+ zend_error (E_WARNING ,
4606+ "\"continue %d\" targeting switch is equivalent to \"break %d\". " \
4607+ "Did you mean to use \"continue %d\"?" ,
4608+ depth , depth , depth + 1 );
4609+ }
4610+ }
4611+ }
4612+
45884613 opline = zend_emit_op (NULL , ast -> kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT , NULL , NULL );
45894614 opline -> op1 .num = CG (context ).current_brk_cont ;
45904615 opline -> op2 .num = depth ;
@@ -4697,7 +4722,7 @@ void zend_compile_while(zend_ast *ast) /* {{{ */
46974722
46984723 opnum_jmp = zend_emit_jump (0 );
46994724
4700- zend_begin_loop (ZEND_NOP , NULL );
4725+ zend_begin_loop (ZEND_NOP , NULL , 0 );
47014726
47024727 opnum_start = get_next_op_number (CG (active_op_array ));
47034728 zend_compile_stmt (stmt_ast );
@@ -4720,7 +4745,7 @@ void zend_compile_do_while(zend_ast *ast) /* {{{ */
47204745 znode cond_node ;
47214746 uint32_t opnum_start , opnum_cond ;
47224747
4723- zend_begin_loop (ZEND_NOP , NULL );
4748+ zend_begin_loop (ZEND_NOP , NULL , 0 );
47244749
47254750 opnum_start = get_next_op_number (CG (active_op_array ));
47264751 zend_compile_stmt (stmt_ast );
@@ -4771,7 +4796,7 @@ void zend_compile_for(zend_ast *ast) /* {{{ */
47714796
47724797 opnum_jmp = zend_emit_jump (0 );
47734798
4774- zend_begin_loop (ZEND_NOP , NULL );
4799+ zend_begin_loop (ZEND_NOP , NULL , 0 );
47754800
47764801 opnum_start = get_next_op_number (CG (active_op_array ));
47774802 zend_compile_stmt (stmt_ast );
@@ -4834,7 +4859,7 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
48344859 opnum_reset = get_next_op_number (CG (active_op_array ));
48354860 opline = zend_emit_op (& reset_node , by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R , & expr_node , NULL );
48364861
4837- zend_begin_loop (ZEND_FE_FREE , & reset_node );
4862+ zend_begin_loop (ZEND_FE_FREE , & reset_node , 0 );
48384863
48394864 opnum_fetch = get_next_op_number (CG (active_op_array ));
48404865 opline = zend_emit_op (NULL , by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R , & reset_node , NULL );
@@ -4989,7 +5014,7 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
49895014
49905015 zend_compile_expr (& expr_node , expr_ast );
49915016
4992- zend_begin_loop (ZEND_FREE , & expr_node );
5017+ zend_begin_loop (ZEND_FREE , & expr_node , 1 );
49935018
49945019 case_node .op_type = IS_TMP_VAR ;
49955020 case_node .u .op .var = get_temporary_variable (CG (active_op_array ));
0 commit comments