@@ -6438,6 +6438,7 @@ static bool can_match_use_jumptable(zend_ast_list *arms) {
64386438}
64396439
64406440static void zend_compile_stmt_list (zend_ast * ast );
6441+ static void zend_compile_block_expr (znode * result , zend_ast * ast , bool omit_free_range );
64416442
64426443static void zend_compile_match (znode * result , zend_ast * ast )
64436444{
@@ -6601,8 +6602,15 @@ static void zend_compile_match(znode *result, zend_ast *ast)
66016602 }
66026603
66036604 znode body_node ;
6604- zend_compile_expr (& body_node , body_ast );
66056605 if (result ) {
6606+ /* Avoid ZEND_FREE_RANGE for block in match expression. Blocks in
6607+ * match arms do not have preceding instructions. The instructions
6608+ * preceding the match are handled by match itself. */
6609+ if (body_ast -> kind == ZEND_AST_BLOCK_EXPR ) {
6610+ zend_compile_block_expr (& body_node , body_ast , /* omit_free_range */ true);
6611+ } else {
6612+ zend_compile_expr (& body_node , body_ast );
6613+ }
66066614 if (is_first_case ) {
66076615 zend_emit_op_tmp (result , ZEND_QM_ASSIGN , & body_node , NULL );
66086616 is_first_case = 0 ;
@@ -6611,7 +6619,7 @@ static void zend_compile_match(znode *result, zend_ast *ast)
66116619 SET_NODE (opline_qm_assign -> result , result );
66126620 }
66136621 } else {
6614- zend_do_free ( & body_node );
6622+ zend_compile_stmt ( body_ast );
66156623 }
66166624
66176625 jmp_end_opnums [i ] = zend_emit_jump (0 );
@@ -11405,6 +11413,36 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
1140511413}
1140611414/* }}} */
1140711415
11416+ static void zend_compile_block_expr (znode * result , zend_ast * ast , bool omit_free_range )
11417+ {
11418+ bool prev_in_block_expr = CG (context ).in_block_expr ;
11419+ CG (context ).in_block_expr = true;
11420+ if (result && !omit_free_range ) {
11421+ zend_loop_var info = {0 };
11422+ info .opcode = ZEND_FREE_RANGE ;
11423+ info .var_type = IS_UNUSED ;
11424+ info .var_num = (uint32_t )-1 ;
11425+ info .opcode_start = get_next_op_number ();
11426+ zend_stack_push (& CG (loop_var_stack ), & info );
11427+ }
11428+ zend_compile_stmt_list (ast -> child [0 ]);
11429+ zend_ast * result_expr_ast = ast -> child [1 ];
11430+ if (result_expr_ast ) {
11431+ if (result ) {
11432+ zend_compile_expr (result , result_expr_ast );
11433+ } else {
11434+ zend_compile_stmt (result_expr_ast );
11435+ }
11436+ } else if (result ) {
11437+ result -> op_type = IS_CONST ;
11438+ ZVAL_NULL (& result -> u .constant );
11439+ }
11440+ if (result && !omit_free_range ) {
11441+ zend_stack_del_top (& CG (loop_var_stack ));
11442+ }
11443+ CG (context ).in_block_expr = prev_in_block_expr ;
11444+ }
11445+
1140811446static void zend_compile_stmt (zend_ast * ast ) /* {{{ */
1140911447{
1141011448 if (!ast ) {
@@ -11507,10 +11545,12 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
1150711545 case ZEND_AST_THROW :
1150811546 zend_compile_expr (NULL , ast );
1150911547 break ;
11510- case ZEND_AST_MATCH : {
11548+ case ZEND_AST_MATCH :
1151111549 zend_compile_match (NULL , ast );
1151211550 break ;
11513- }
11551+ case ZEND_AST_BLOCK_EXPR :
11552+ zend_compile_block_expr (NULL , ast , /* omit_free_range */ false);
11553+ return ;
1151411554 default :
1151511555 {
1151611556 znode result ;
@@ -11525,21 +11565,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
1152511565}
1152611566/* }}} */
1152711567
11528- static void zend_compile_block_expr (znode * result , zend_ast * ast )
11529- {
11530- bool prev_in_block_expr = CG (context ).in_block_expr ;
11531- CG (context ).in_block_expr = true;
11532- zend_compile_stmt_list (ast -> child [0 ]);
11533- zend_ast * result_expr_ast = ast -> child [1 ];
11534- if (result_expr_ast ) {
11535- zend_compile_expr (result , result_expr_ast );
11536- } else {
11537- result -> op_type = IS_CONST ;
11538- ZVAL_NULL (& result -> u .constant );
11539- }
11540- CG (context ).in_block_expr = prev_in_block_expr ;
11541- }
11542-
1154311568static void zend_compile_expr_inner (znode * result , zend_ast * ast ) /* {{{ */
1154411569{
1154511570 /* CG(zend_lineno) = ast->lineno; */
@@ -11677,7 +11702,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
1167711702 zend_compile_match (result , ast );
1167811703 return ;
1167911704 case ZEND_AST_BLOCK_EXPR :
11680- zend_compile_block_expr (result , ast );
11705+ zend_compile_block_expr (result , ast , /* omit_free_range */ false );
1168111706 return ;
1168211707 default :
1168311708 ZEND_ASSERT (0 /* not supported */ );
0 commit comments