mirror of
https://github.com/php/php-src.git
synced 2026-04-29 11:13:36 +02:00
An exception thrown in try or catch block is disacarded by return statement in finally block.
This commit is contained in:
@@ -25,4 +25,4 @@ try {
|
||||
--EXPECT--
|
||||
string(4) "para"
|
||||
string(7) "finally"
|
||||
string(2) "ex"
|
||||
string(6) "return"
|
||||
|
||||
@@ -15,11 +15,9 @@ function foo () {
|
||||
die("error");
|
||||
} finally {
|
||||
echo "1";
|
||||
return 1;
|
||||
}
|
||||
} finally {
|
||||
echo "2";
|
||||
return 2;
|
||||
}
|
||||
} catch (BE $e) {
|
||||
die("error");
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Try finally (function call in the finaly block after exception)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
echo "4";
|
||||
}
|
||||
function bar() {
|
||||
try {
|
||||
echo "2";
|
||||
throw new Exception();
|
||||
echo "x";
|
||||
} catch (MyEx $ex) {
|
||||
echo "x";
|
||||
} finally {
|
||||
echo "3";
|
||||
foo();
|
||||
echo "5";
|
||||
}
|
||||
}
|
||||
try {
|
||||
echo "1";
|
||||
bar();
|
||||
echo "x";
|
||||
} catch (Exception $ex) {
|
||||
echo "6";
|
||||
}
|
||||
echo "\n";
|
||||
--EXPECT--
|
||||
123456
|
||||
+13
-1
@@ -181,6 +181,7 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */
|
||||
CG(context).backpatch_count = 0;
|
||||
CG(context).nested_calls = 0;
|
||||
CG(context).used_stack = 0;
|
||||
CG(context).in_finally = 0;
|
||||
CG(context).labels = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -287,7 +288,7 @@ ZEND_API zend_bool zend_is_compiling(TSRMLS_D) /* {{{ */
|
||||
|
||||
static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
|
||||
{
|
||||
return EX_TMP_VAR_NUM(0, (op_array->T)++);
|
||||
return (zend_uint)EX_TMP_VAR_NUM(0, (op_array->T)++);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -2671,6 +2672,13 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
|
||||
start_op_number++;
|
||||
}
|
||||
|
||||
if (CG(context).in_finally) {
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
opline->opcode = ZEND_DISCARD_EXCEPTION;
|
||||
SET_UNUSED(opline->op1);
|
||||
SET_UNUSED(opline->op2);
|
||||
}
|
||||
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
opline->opcode = returns_reference ? ZEND_RETURN_BY_REF : ZEND_RETURN;
|
||||
@@ -2819,6 +2827,8 @@ void zend_do_finally(znode *finally_token TSRMLS_DC) /* {{{ */
|
||||
opline->opcode = ZEND_JMP;
|
||||
SET_UNUSED(opline->op1);
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
CG(context).in_finally++;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -2897,6 +2907,8 @@ void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_to
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
CG(active_op_array)->opcodes[finally_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
|
||||
|
||||
CG(context).in_finally--;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -61,6 +61,7 @@ typedef struct _zend_compiler_context {
|
||||
int backpatch_count;
|
||||
int nested_calls;
|
||||
int used_stack;
|
||||
int in_finally;
|
||||
HashTable *labels;
|
||||
} zend_compiler_context;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/* The first number is the engine version and the rest is the date.
|
||||
* This way engine 2/3 API no. is always greater than engine 1 API no..
|
||||
*/
|
||||
#define ZEND_EXTENSION_API_NO 220121204
|
||||
#define ZEND_EXTENSION_API_NO 220121212
|
||||
|
||||
typedef struct _zend_extension_version_info {
|
||||
int zend_extension_api_no;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@
|
||||
#define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC
|
||||
#define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC
|
||||
|
||||
#define ZEND_MODULE_API_NO 20121204
|
||||
#define ZEND_MODULE_API_NO 20121212
|
||||
#ifdef ZTS
|
||||
#define USING_ZTS 1
|
||||
#else
|
||||
|
||||
+11
-12
@@ -1845,12 +1845,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||
zend_bool nested;
|
||||
zend_op_array *op_array = EX(op_array);
|
||||
|
||||
if (EXPECTED(EG(exception) == NULL) &&
|
||||
UNEXPECTED(EG(prev_exception) != NULL)) {
|
||||
/* return from finally block called because of unhandled exception */
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
}
|
||||
|
||||
EG(current_execute_data) = EX(prev_execute_data);
|
||||
EG(opline_ptr) = NULL;
|
||||
if (!EG(active_symbol_table)) {
|
||||
@@ -2960,12 +2954,6 @@ ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, ANY, ANY)
|
||||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (EXPECTED(EG(exception) == NULL) &&
|
||||
UNEXPECTED(EG(prev_exception) != NULL)) {
|
||||
/* return from finally block called because of unhandled exception */
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
}
|
||||
|
||||
/* Close the generator to free up resources */
|
||||
zend_generator_close(generator, 1 TSRMLS_CC);
|
||||
|
||||
@@ -5409,6 +5397,17 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
|
||||
ZEND_VM_RETURN();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
|
||||
{
|
||||
if (EG(prev_exception) != NULL) {
|
||||
/* discard the previously thrown exception */
|
||||
zval_ptr_dtor(&EG(prev_exception));
|
||||
EG(prev_exception) = NULL;
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
+36
-37
@@ -386,12 +386,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_bool nested;
|
||||
zend_op_array *op_array = EX(op_array);
|
||||
|
||||
if (EXPECTED(EG(exception) == NULL) &&
|
||||
UNEXPECTED(EG(prev_exception) != NULL)) {
|
||||
/* return from finally block called because of unhandled exception */
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
}
|
||||
|
||||
EG(current_execute_data) = EX(prev_execute_data);
|
||||
EG(opline_ptr) = NULL;
|
||||
if (!EG(active_symbol_table)) {
|
||||
@@ -696,12 +690,6 @@ static int ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER
|
||||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (EXPECTED(EG(exception) == NULL) &&
|
||||
UNEXPECTED(EG(prev_exception) != NULL)) {
|
||||
/* return from finally block called because of unhandled exception */
|
||||
zend_exception_restore(TSRMLS_C);
|
||||
}
|
||||
|
||||
/* Close the generator to free up resources */
|
||||
zend_generator_close(generator, 1 TSRMLS_CC);
|
||||
|
||||
@@ -1134,6 +1122,17 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
||||
}
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
if (EG(prev_exception) != NULL) {
|
||||
/* discard the previously thrown exception */
|
||||
zval_ptr_dtor(&EG(prev_exception));
|
||||
EG(prev_exception) = NULL;
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@@ -44827,31 +44826,31 @@ void zend_init_opcodes_handlers(void)
|
||||
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
|
||||
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
|
||||
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
|
||||
ZEND_YIELD_SPEC_CONST_CONST_HANDLER,
|
||||
ZEND_YIELD_SPEC_CONST_TMP_HANDLER,
|
||||
ZEND_YIELD_SPEC_CONST_VAR_HANDLER,
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
#define ZEND_SEPARATE 156
|
||||
#define ZEND_QM_ASSIGN_VAR 157
|
||||
#define ZEND_JMP_SET_VAR 158
|
||||
#define ZEND_DISCARD_EXCEPTION 159
|
||||
#define ZEND_YIELD 160
|
||||
#define ZEND_GENERATOR_RETURN 161
|
||||
#define ZEND_FAST_CALL 162
|
||||
|
||||
Reference in New Issue
Block a user