]> granicus.if.org Git - php/commitdiff
Fix type inference bugs
authorNikita Popov <nikic@php.net>
Wed, 8 Jun 2016 20:21:36 +0000 (22:21 +0200)
committerNikita Popov <nikic@php.net>
Wed, 15 Jun 2016 20:52:48 +0000 (22:52 +0200)
* Add proper array_key_any|array_of_any|array_of_ref in some more
  places
* strlen() on objects may be null
* IS fetch on string dim may be null

ext/opcache/Optimizer/zend_inference.c

index 0a15e4b09f6f0ec6be4d2edd98048840da5e5405..c8024d0f86bdd1acb585f83e5cfaaf0bd991e626 100644 (file)
@@ -2524,7 +2524,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
                        if (opline->extended_value == ZEND_ASSIGN_OBJ) {
                                tmp = MAY_BE_RC1;
                                orig = t1 & ~MAY_BE_UNDEF;
-                               t1 = MAY_BE_ANY;
+                               t1 = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
                                t2 = OP1_DATA_INFO();
                        } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
                                tmp = MAY_BE_RC1;
@@ -2801,11 +2801,13 @@ static void zend_update_type_info(const zend_op_array *op_array,
                        }
                        break;
                case ZEND_BIND_GLOBAL:
-                       tmp = (MAY_BE_REF | MAY_BE_ANY);
+                       tmp = MAY_BE_REF | MAY_BE_ANY
+                               | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
                        UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
                        break;
                case ZEND_BIND_STATIC:
-                       tmp = MAY_BE_ANY | (opline->extended_value ? MAY_BE_REF : (MAY_BE_RC1 | MAY_BE_RCN));
+                       tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF
+                               | (opline->extended_value ? MAY_BE_REF : (MAY_BE_RC1 | MAY_BE_RCN));
                        UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
                        break;
                case ZEND_SEND_VAR:
@@ -3239,6 +3241,8 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                } else if (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) {
                                        tmp |= MAY_BE_ERROR;
                                }
+                       } else if (opline->opcode == ZEND_FETCH_DIM_IS && (t1 & MAY_BE_STRING)) {
+                               tmp |= MAY_BE_NULL;
                        }
                        UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
                        break;
@@ -3319,7 +3323,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
                        break;
                case ZEND_STRLEN:
                        tmp = MAY_BE_RC1|MAY_BE_LONG;
-                       if (t1 & (MAY_BE_ANY - (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT))) {
+                       if (t1 & (MAY_BE_ANY - (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING))) {
                                tmp |= MAY_BE_NULL;
                        }
                        UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);