summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-02-25 20:07:02 +0800
committerXinchen Hui <laruence@php.net>2015-02-25 20:07:02 +0800
commitd508ff9640469bf451b975d83fd2879710db0b46 (patch)
treeddf2d0c7c67dee3fe1a4f813053497f47be526da
parentffdc5728c8d0c1cc31e2a13d1d7a03e85a85e7f0 (diff)
downloadphp-git-d508ff9640469bf451b975d83fd2879710db0b46.tar.gz
Improve fix for #69038
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c15
-rw-r--r--ext/opcache/tests/bug69038.phpt10
2 files changed, 20 insertions, 5 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 7829ee7c95..6da3370ffe 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -290,15 +290,24 @@ static void replace_tmp_by_const(zend_op_array *op_array,
* and allows its reuse. The number of ZEND_CASE instructions
* usually terminated by ZEND_FREE that finally kills the value.
*/
- if (opline->opcode == ZEND_CASE) {
+ if (opline->opcode == ZEND_CASE || opline->opcode == ZEND_FREE) {
zend_op *m, *n;
int brk = op_array->last_brk_cont;
+ zend_bool in_case = 0;
while (brk--) {
if (op_array->brk_cont_array[brk].start <= (opline - op_array->opcodes) &&
op_array->brk_cont_array[brk].brk > (opline - op_array->opcodes)) {
+ in_case = 1;
break;
}
}
+
+ if (!in_case) {
+ MAKE_NOP(opline);
+ zval_dtor(val);
+ break;
+ }
+
m = opline;
n = op_array->opcodes + op_array->brk_cont_array[brk].brk + 1;
while (m < n) {
@@ -320,10 +329,6 @@ static void replace_tmp_by_const(zend_op_array *op_array,
}
zval_dtor(val);
break;
- } else if (opline->opcode == ZEND_FREE) {
- MAKE_NOP(opline);
- zval_dtor(val);
- break;
} else {
update_op1_const(op_array, opline, val TSRMLS_CC);
break;
diff --git a/ext/opcache/tests/bug69038.phpt b/ext/opcache/tests/bug69038.phpt
index 9aeecfeece..bba3c33cb6 100644
--- a/ext/opcache/tests/bug69038.phpt
+++ b/ext/opcache/tests/bug69038.phpt
@@ -39,7 +39,17 @@ function b($b = "bad") {
return $b;
}
var_dump(b());
+
+function c() {
+ switch (PHP_OS) {
+ default: return "bad";
+ case PHP_OS: return "okey";
+ }
+}
+
+var_dump(c());
?>
--EXPECT--
string(4) "okey"
string(4) "okey"
+string(4) "okey"