Skip to content

Commit 8c3f701

Browse files
committed
Fixed exception catching on break/continue
Fixed "finaly" handling on exception in "return" statement
1 parent 788c4c8 commit 8c3f701

File tree

6 files changed

+58
-14
lines changed

6 files changed

+58
-14
lines changed

Zend/tests/return_types/031.phpt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Excepton on return types mismutch shouldn't execute "catch" code but should execute "finally" code.
3+
--FILE--
4+
<?php
5+
6+
function foo(): string {
7+
$a = "OK\n";
8+
try {
9+
return $a; // invalid return type
10+
} catch (TypeError $e) {
11+
echo "BAG!\n";
12+
return "ops!\n";
13+
} finally {
14+
echo "finally1\n";
15+
}
16+
}
17+
function bar(): string {
18+
$a = [];
19+
try {
20+
return $a; // invalid return type
21+
} catch (TypeError $e) {
22+
echo "BAG!\n";
23+
return "ops!\n";
24+
} finally {
25+
echo "finally2\n";
26+
}
27+
}
28+
try {
29+
echo foo();
30+
} catch (TypeError $e) {
31+
echo "BAG\n";
32+
}
33+
try {
34+
echo bar();
35+
} catch (TypeError $e) {
36+
echo "OK\n";
37+
}
38+
?>
39+
--EXPECT--
40+
finally1
41+
OK
42+
finally2
43+
OK

Zend/zend_compile.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3482,7 +3482,7 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
34823482
zend_emit_return_type_check(expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1);
34833483
}
34843484

3485-
zend_free_foreach_and_switch_variables(ZEND_FREE_ON_JUMP);
3485+
zend_free_foreach_and_switch_variables(ZEND_FREE_ON_RETURN);
34863486

34873487
if (CG(context).in_finally) {
34883488
opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL);
@@ -3567,7 +3567,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
35673567
}
35683568

35693569
if (nest_level > 1) {
3570-
generate_free_loop_var_ex(&CG(context).brk_cont_array[array_offset].loop_var, ZEND_FREE_ON_JUMP);
3570+
generate_free_loop_var_ex(&CG(context).brk_cont_array[array_offset].loop_var, ZEND_FREE_ON_BREAK);
35713571
}
35723572

35733573
array_offset = CG(context).brk_cont_array[array_offset].parent;
@@ -3637,7 +3637,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
36373637
if (pass2_opline) {
36383638
free_vars++;
36393639
} else {
3640-
generate_free_loop_var_ex(&CG(context).brk_cont_array[current].loop_var, ZEND_FREE_ON_JUMP);
3640+
generate_free_loop_var_ex(&CG(context).brk_cont_array[current].loop_var, ZEND_FREE_ON_BREAK);
36413641
}
36423642
}
36433643
current = CG(context).brk_cont_array[current].parent;

Zend/zend_compile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,8 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
882882

883883
#define ZEND_FETCH_ARG_MASK 0x000fffff
884884

885-
#define ZEND_FREE_ON_JUMP (1<<0)
885+
#define ZEND_FREE_ON_RETURN (1<<0)
886+
#define ZEND_FREE_ON_BREAK (1<<1)
886887

887888
#define ZEND_MEMBER_FUNC_CALL (1<<0)
888889

Zend/zend_opcode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -994,8 +994,8 @@ static zend_always_inline uint32_t *generate_var_liveliness_info_ex(zend_op_arra
994994
&& opline->opcode != ZEND_FE_FETCH_RW
995995
/* the following opcodes are parts of "return" statement */
996996
&& opline->opcode != ZEND_VERIFY_RETURN_TYPE
997-
&& (opline->opcode != ZEND_FREE || !(opline->extended_value & ZEND_FREE_ON_JUMP))
998-
&& (opline->opcode != ZEND_FE_FREE || !(opline->extended_value & ZEND_FREE_ON_JUMP))
997+
&& (opline->opcode != ZEND_FREE || !(opline->extended_value & (ZEND_FREE_ON_RETURN|ZEND_FREE_ON_BREAK)))
998+
&& (opline->opcode != ZEND_FE_FREE || !(opline->extended_value & (ZEND_FREE_ON_RETURN|ZEND_FREE_ON_BREAK)))
999999
) {
10001000
op_live_total += liveliness_kill_var(op_array, opline, var, Tstart, opTs);
10011001
}

Zend/zend_vm_def.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7082,12 +7082,12 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
70827082
}
70837083
}
70847084

7085-
if (catch_op_num || finally_op_num) {
7085+
if (catch_op_num) {
70867086
if (EX(func)->op_array.opcodes[op_num].opcode == ZEND_VERIFY_RETURN_TYPE
7087-
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP))
7088-
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP))
7087+
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN))
7088+
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN))
70897089
) {
7090-
catch_op_num = finally_op_num = 0;
7090+
catch_op_num = 0;
70917091
}
70927092
}
70937093

Zend/zend_vm_execute.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,12 +1500,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
15001500
}
15011501
}
15021502

1503-
if (catch_op_num || finally_op_num) {
1503+
if (catch_op_num) {
15041504
if (EX(func)->op_array.opcodes[op_num].opcode == ZEND_VERIFY_RETURN_TYPE
1505-
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP))
1506-
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP))
1505+
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN))
1506+
|| (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN))
15071507
) {
1508-
catch_op_num = finally_op_num = 0;
1508+
catch_op_num = 0;
15091509
}
15101510
}
15111511

0 commit comments

Comments
 (0)