]> granicus.if.org Git - php/commitdiff
Fixed reference-counter inference
authorDmitry Stogov <dmitry@zend.com>
Mon, 31 Oct 2016 16:51:19 +0000 (19:51 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 31 Oct 2016 16:51:19 +0000 (19:51 +0300)
ext/opcache/Optimizer/zend_dfg.c
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_ssa.c

index 693fcc8e5127acb8d422cb8fd55f6dbe037d1b33..6c52d6eb58e23ea5a807212bf9df68d5657b44ee 100644 (file)
@@ -76,6 +76,9 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
                                        case ZEND_FE_RESET_R:
                                        case ZEND_SEND_VAR:
                                        case ZEND_CAST:
+                                       case ZEND_QM_ASSIGN:
+                                       case ZEND_JMP_SET:
+                                       case ZEND_COALESCE:
                                                if (build_flags & ZEND_SSA_RC_INFERENCE) {
                                                        goto op1_def;
                                                }
index 0635cc511923411535ae06ffc7b39f101e5a7f8a..1fff94ea19352f0d9a9dde1d7a17eb9166bcdbbf 100644 (file)
@@ -1054,6 +1054,17 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
                case ZEND_QM_ASSIGN:
                case ZEND_JMP_SET:
                case ZEND_COALESCE:
+                       if (ssa->ops[line].op1_def == var) {
+                               if (ssa->ops[line].op1_def >= 0) {
+                                       if (OP1_HAS_RANGE()) {
+                                               tmp->underflow = OP1_RANGE_UNDERFLOW();
+                                               tmp->min = OP1_MIN_RANGE();
+                                               tmp->max = OP1_MAX_RANGE();
+                                               tmp->overflow  = OP1_RANGE_OVERFLOW();
+                                               return 1;
+                                       }
+                               }
+                       }
                        if (ssa->ops[line].result_def == var) {
                                if (OP1_HAS_RANGE()) {
                                        tmp->min = OP1_MIN_RANGE();
@@ -2549,6 +2560,14 @@ static void zend_update_type_info(const zend_op_array *op_array,
                case ZEND_QM_ASSIGN:
                case ZEND_JMP_SET:
                case ZEND_COALESCE:
+                       if (ssa_ops[i].op1_def >= 0) {
+                               tmp = t1;
+                               if ((t1 & (MAY_BE_RC1|MAY_BE_REF)) && (opline->op1_type == IS_CV)) {
+                                       tmp |= MAY_BE_RCN;
+                               }
+                               UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
+                               COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def);
+                       }
                        tmp = t1 & ~(MAY_BE_UNDEF|MAY_BE_REF);
                        if (t1 & MAY_BE_UNDEF) {
                                tmp |= MAY_BE_NULL;
index a0a2df92de95270f3cf6d3db3580b49cffffd76f..537258394fe564d637e48e88a0531d2c02a28302 100644 (file)
@@ -656,6 +656,9 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
                                        break;
                                case ZEND_SEND_VAR:
                                case ZEND_CAST:
+                               case ZEND_QM_ASSIGN:
+                               case ZEND_JMP_SET:
+                               case ZEND_COALESCE:
                                        if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
                                                ssa_ops[k].op1_def = ssa_vars_count;
                                                var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;