summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-07-08 17:15:09 +0800
committerXinchen Hui <laruence@php.net>2015-07-08 17:15:09 +0800
commitc6037bd3af5cc9f42fe02eae2a2066185ba67a69 (patch)
tree09a26041aa289e949bcee21b894714638968b158
parent6154fc77be8eff09736c2f15b350ae07bec72816 (diff)
downloadphp-git-c6037bd3af5cc9f42fe02eae2a2066185ba67a69.tar.gz
Fixed bug #70012 (Exception lost with nested finally block)
-rw-r--r--NEWS3
-rw-r--r--Zend/tests/bug70012.phpt32
-rw-r--r--Zend/zend_vm_def.h9
-rw-r--r--Zend/zend_vm_execute.h9
-rw-r--r--ext/opcache/Optimizer/optimize_temp_vars_5.c5
5 files changed, 50 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index b5a4e44412..53828b0e81 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
23 Jul 2015, PHP 7.0.0 Beta 2
+- Core:
+ . Fixed bug #70012 (Exception lost with nested finally block). (Laruence)
+
09 Jul 2015, PHP 7.0.0 Beta 1
- Core:
diff --git a/Zend/tests/bug70012.phpt b/Zend/tests/bug70012.phpt
new file mode 100644
index 0000000000..5337649d2d
--- /dev/null
+++ b/Zend/tests/bug70012.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #70012 (Exception lost with nested finally block)
+--FILE--
+<?php
+try {
+ echo "Outer try\n";
+ try {
+ echo " Middle try\n";
+ throw new Exception();
+ } finally {
+ echo " Middle finally\n";
+ try {
+ echo " Inner try\n";
+ } finally {
+ echo " Inner finally\n";
+ }
+ }
+ echo "Outer shouldnt get here\n";
+} catch (Exception $e) {
+ echo "Outer catch\n";
+} finally {
+ echo "Outer finally\n";
+}
+?>
+--EXPECT--
+Outer try
+ Middle try
+ Middle finally
+ Inner try
+ Inner finally
+Outer catch
+Outer finally
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index cff901164e..db746a647c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -7596,9 +7596,12 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
ZEND_VM_CONTINUE();
}
/* set no delayed exception */
- Z_OBJ_P(fast_call) = NULL;
- /* set return address */
- fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
+ if (UNEXPECTED(Z_OBJ_P(fast_call) != NULL)) {
+ fast_call->u2.lineno = (uint32_t)-1;
+ } else {
+ /* set return address */
+ fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
+ }
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
ZEND_VM_CONTINUE();
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 720af1acd4..832692d1db 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1608,9 +1608,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OP
ZEND_VM_CONTINUE();
}
/* set no delayed exception */
- Z_OBJ_P(fast_call) = NULL;
- /* set return address */
- fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
+ if (UNEXPECTED(Z_OBJ_P(fast_call) != NULL)) {
+ fast_call->u2.lineno = (uint32_t)-1;
+ } else {
+ /* set return address */
+ fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
+ }
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
ZEND_VM_CONTINUE();
}
diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c
index 77b4d66f94..de170d2295 100644
--- a/ext/opcache/Optimizer/optimize_temp_vars_5.c
+++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c
@@ -77,7 +77,6 @@ void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *c
while (opline >= end) {
if ((ZEND_OP1_TYPE(opline) & (IS_VAR | IS_TMP_VAR))) {
-
currT = VAR_NUM(ZEND_OP1(opline).var) - offset;
if (opline->opcode == ZEND_ROPE_END) {
int num = (((opline->extended_value + 1) * sizeof(zend_string*)) + (sizeof(zval) - 1)) / sizeof(zval);
@@ -153,7 +152,9 @@ void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *c
currT = VAR_NUM(ZEND_RESULT(opline).var) - offset;
if (valid_T[currT]) {
if (start_of_T[currT] == opline) {
- taken_T[map_T[currT]] = 0;
+ if (opline->opcode != ZEND_FAST_CALL) {
+ taken_T[map_T[currT]] = 0;
+ }
}
ZEND_RESULT(opline).var = NUM_VAR(map_T[currT] + offset);
if (opline->opcode == ZEND_ROPE_INIT) {