]> granicus.if.org Git - php/commitdiff
Prevent wrong optimization
authorDmitry Stogov <dmitry@zend.com>
Wed, 13 Jul 2016 12:05:11 +0000 (15:05 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 13 Jul 2016 12:05:11 +0000 (15:05 +0300)
ext/opcache/Optimizer/block_pass.c

index 02fb8192a66ee2963b730af41b07cb99a1b1f331..3bd86e60c0edcba54096e55561787ad2a42f41fb 100644 (file)
@@ -733,10 +733,26 @@ optimize_const_unary_op:
                                if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
                                        src = VAR_SOURCE(opline->op1);
                                        if (src && src->opcode == ZEND_QM_ASSIGN) {
-                                               /* T = QM_ASSIGN(X), RETURN(T) to NOP, RETURN(X) */
-                                               VAR_SOURCE(opline->op1) = NULL;
-                                               COPY_NODE(opline->op1, src->op1);
-                                               MAKE_NOP(src);
+                                               zend_op *op = src + 1;
+                                               zend_bool optimize = 1;
+
+                                               while (op < opline) {
+                                                       if ((op->op1_type == opline->op1_type
+                                                         && op->op1.var == opline->op1.var)
+                                                        || (op->op2_type == opline->op1_type
+                                                         && op->op2.var == opline->op1.var)) {
+                                                               optimize = 0;
+                                                               break;
+                                                       }
+                                                       op++;
+                                               }
+
+                                               if (optimize) {
+                                                       /* T = QM_ASSIGN(X), RETURN(T) to NOP, RETURN(X) */
+                                                       VAR_SOURCE(opline->op1) = NULL;
+                                                       COPY_NODE(opline->op1, src->op1);
+                                                       MAKE_NOP(src);
+                                               }
                                        }
                                }
                                break;