summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_optimizer.c
diff options
context:
space:
mode:
authorFerenc Kovacs <tyrael@php.net>2014-06-04 03:22:00 +0200
committerFerenc Kovacs <tyrael@php.net>2014-06-04 03:22:00 +0200
commit4ed171378978f3259af726d51ebfa50c1610106f (patch)
tree64142d5cabae688ec9d02abc612c2b9950858c0e /ext/opcache/Optimizer/zend_optimizer.c
parent57e698d58263edeb5e15d78e0a968298f65a439f (diff)
parent848df6fcbe7b32f2c21ebdcfe1c1adb56753cad9 (diff)
downloadphp-git-4ed171378978f3259af726d51ebfa50c1610106f.tar.gz
Merge branch 'PHP-5.6' into PHP-5.6.0
* PHP-5.6: (51 commits) Fix tests Fix possible segfault depending on memory location... fix gcov data with some locales (again) Update NEWS Fixed startup segfault in non-debug builds Fixes issue #87 Fixed regression introduced by patch for bug #67072 Fixed bug #67329 fileinfo: NULL pointer deference flaw by processing certain CDF files (re)add cve number in NEWS, from 5.4.29 NEWS NEWS NEWS Fix bug #67326 fileinfo: cdf_read_short_sector insufficient boundary check add NEWS block for 5.6.0RC1 Update NEWs Update NEWs Fixed bug #67359 (Segfault in recursiveDirectoryIterator) Check for zero-length keys in spl_array_skip_protected and don't skip them. added CVEs in NEWS updated libmagic.patch for 5.6+ updated libmagic.patch for 5.4+ ... Conflicts: NEWS
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 973ba3aaac..fc7d0a29b3 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -367,20 +367,41 @@ static void replace_tmp_by_const(zend_op_array *op_array,
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP1(opline).var == var) {
- update_op1_const(op_array, opline, val TSRMLS_CC);
- /* TMP_VAR my be used only once */
- break;
+ /* In most cases IS_TMP_VAR operand may be used only once.
+ * The operands are usually destroyed by the opcode handler.
+ * ZEND_CASE is an exception, that keeps operand unchanged,
+ * 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) {
+ zval old_val;
+ old_val = *val;
+ zval_copy_ctor(val);
+ update_op1_const(op_array, opline, val TSRMLS_CC);
+ *val = old_val;
+ } else if (opline->opcode == ZEND_FREE) {
+ MAKE_NOP(opline);
+ break;
+ } else {
+ update_op1_const(op_array, opline, val TSRMLS_CC);
+ val = NULL;
+ break;
+ }
}
if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP2(opline).var == var) {
update_op2_const(op_array, opline, val TSRMLS_CC);
- /* TMP_VAR my be used only once */
+ /* TMP_VAR may be used only once */
+ val = NULL;
break;
}
opline++;
}
+ if (val) {
+ zval_dtor(val);
+ }
}
#include "Optimizer/nop_removal.c"