]> granicus.if.org Git - php/commitdiff
More type inferences fixes
authorNikita Popov <nikic@php.net>
Thu, 16 Jun 2016 12:41:33 +0000 (14:41 +0200)
committerNikita Popov <nikic@php.net>
Tue, 28 Jun 2016 09:49:50 +0000 (11:49 +0200)
ext/opcache/Optimizer/zend_func_info.c
ext/opcache/Optimizer/zend_inference.c

index c53e042e9f73c021d505d9af2c3a49be85ec5f01..0097e308641dbb70c80e817f707db19deba6271b 100644 (file)
@@ -100,26 +100,23 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa
                uint32_t t1 = _ssa_op1_info(call_info->caller_op_array, ssa, call_info->arg_info[0].opline);
                uint32_t t2 = _ssa_op1_info(call_info->caller_op_array, ssa, call_info->arg_info[1].opline);
                uint32_t t3 = 0;
-               uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG;
+               uint32_t tmp = FUNC_MAY_WARN | MAY_BE_RC1 | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG;
 
                if (call_info->num_args == 3) {
                        t3 = _ssa_op1_info(call_info->caller_op_array, ssa, call_info->arg_info[2].opline);
                }
                if ((t1 & MAY_BE_STRING) && (t2 & MAY_BE_STRING)) {
                        tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING;
-                       tmp |= FUNC_MAY_WARN | MAY_BE_FALSE;
                }
-               if ((t1 & MAY_BE_DOUBLE) || (t2 & MAY_BE_DOUBLE) || (t3 & MAY_BE_DOUBLE)) {
+               if ((t1 & (MAY_BE_DOUBLE|MAY_BE_STRING))
+                               || (t2 & (MAY_BE_DOUBLE|MAY_BE_STRING))
+                               || (t3 & (MAY_BE_DOUBLE|MAY_BE_STRING))) {
                        tmp |= MAY_BE_ARRAY_OF_DOUBLE;
-                       tmp |= FUNC_MAY_WARN | MAY_BE_FALSE;
                }
                if ((t1 & (MAY_BE_ANY-(MAY_BE_STRING|MAY_BE_DOUBLE))) && (t2 & (MAY_BE_ANY-(MAY_BE_STRING|MAY_BE_DOUBLE)))) {
-                       if (call_info->num_args == 2 && !(t3 & MAY_BE_DOUBLE)) {
+                       if ((t3 & MAY_BE_ANY) != MAY_BE_DOUBLE) {
                                tmp |= MAY_BE_ARRAY_OF_LONG;
                        }
-                       if (call_info->num_args == 3) {
-                               tmp |= FUNC_MAY_WARN | MAY_BE_FALSE;
-                       }
                }
                return tmp;
        } else {
@@ -294,8 +291,8 @@ static const func_info_t func_infos[] = {
        F1("crc32",                        MAY_BE_NULL | MAY_BE_LONG),
        F1("iptcparse",                    MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ARRAY),
        F1("iptcembed",                    MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING),
-       F1("getimagesize",                 MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING),
-       F1("getimagesizefromstring",       MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING),
+       F1("getimagesize",                 MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING),
+       F1("getimagesizefromstring",       MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING),
        F1("image_type_to_mime_type",      MAY_BE_NULL | MAY_BE_STRING),
        F1("image_type_to_extension",      MAY_BE_FALSE | MAY_BE_STRING),
        F1("phpinfo",                      MAY_BE_NULL | MAY_BE_TRUE),
@@ -495,7 +492,7 @@ static const func_info_t func_infos[] = {
 #ifdef HAVE_PUTENV
        F1("putenv",                       MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
 #endif
-       F1("getopt",                       MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_FALSE | MAY_BE_ARRAY_OF_TRUE | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
+       F1("getopt",                       MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_FALSE | MAY_BE_ARRAY_OF_TRUE | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
 #ifdef HAVE_GETLOADAVG
        F1("sys_getloadavg",               MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_DOUBLE),
 #endif
@@ -752,7 +749,7 @@ static const func_info_t func_infos[] = {
        F1("disk_free_space",              MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_DOUBLE),
        F1("diskfreespace",                MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_DOUBLE),
        F1("realpath_cache_size",          MAY_BE_NULL | MAY_BE_LONG),
-       F1("realpath_cache_get",           MAY_BE_NULL | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_FALSE | MAY_BE_ARRAY_OF_TRUE | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING),
+       F1("realpath_cache_get",           MAY_BE_NULL | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ARRAY),
        F1("mail",                         MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
        F1("ezmlm_hash",                   MAY_BE_NULL | MAY_BE_LONG),
 #ifdef HAVE_SYSLOG_H
index 1e6e50b3ef28f0963bde88cf5acb55cc352c8114..ba59524d44f1326288c1e4ef532684ad629bf86e 100644 (file)
@@ -3022,8 +3022,11 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                tmp = MAY_BE_RC1|MAY_BE_ARRAY;
                                if (opline->op1_type != IS_UNUSED) {
                                        tmp |= (t1 & MAY_BE_ANY) << MAY_BE_ARRAY_SHIFT;
+                                       if (t1 & MAY_BE_UNDEF) {
+                                               tmp |= MAY_BE_ARRAY_OF_NULL;
+                                       }
                                        if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) {
-                                               tmp |= MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
+                                               tmp |= MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
                                        }
                                }
                                if (ssa_ops[i].result_use >= 0) {
@@ -3065,10 +3068,6 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def);
                        }
                        break;
-//             case ZEND_INCLUDE_OR_EVAL:
-//             case ZEND_ISSET_ISEMPTY_VAR:
-// TODO: ???
-//                     break;
                case ZEND_FE_RESET_R:
                case ZEND_FE_RESET_RW:
                        if (ssa_ops[i].op1_def >= 0) {
@@ -3145,9 +3144,6 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
                        }
                        break;
-//             case ZEND_CATCH:
-// TODO: ???
-//                     break;
                case ZEND_FETCH_DIM_R:
                case ZEND_FETCH_DIM_IS:
                case ZEND_FETCH_DIM_RW:
@@ -3172,17 +3168,23 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                        if (tmp & MAY_BE_RCN) {
                                                tmp |= MAY_BE_RC1;
                                        }
-                                       if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
+                                       if (opline->op2_type == IS_UNUSED) {
                                                tmp |= MAY_BE_ARRAY_KEY_LONG;
+                                       } else {
+                                               if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
+                                                       tmp |= MAY_BE_ARRAY_KEY_LONG;
+                                               }
+                                               if (t2 & MAY_BE_STRING) {
+                                                       tmp |= MAY_BE_ARRAY_KEY_STRING;
+                                                       if (opline->op2_type != IS_CONST) {
+                                                               // FIXME: numeric string
+                                                               tmp |= MAY_BE_ARRAY_KEY_LONG;
+                                                       }
+                                               }
+                                               if (t2 & (MAY_BE_UNDEF | MAY_BE_NULL)) {
+                                                       tmp |= MAY_BE_ARRAY_KEY_STRING;
+                                               }
                                        }
-                                       if (t2 & (MAY_BE_STRING)) {
-                                               // FIXME: numeric string
-                                               tmp |= MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_KEY_LONG;
-                                       }
-                                       if (t2 & (MAY_BE_UNDEF | MAY_BE_NULL)) {
-                                               tmp |= MAY_BE_ARRAY_KEY_STRING;
-                                       }
-
                                }
                                ZEND_ASSERT(!ssa_vars[ssa_ops[i].result_def].phi_use_chain);
                                j = ssa_vars[ssa_ops[i].result_def].use_chain;
@@ -3206,14 +3208,27 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                                case ZEND_ASSIGN_DIM:
                                                        tmp |= MAY_BE_ARRAY | MAY_BE_ARRAY_OF_ARRAY;
                                                        break;
-                                               case ZEND_SEND_VAR:
+                                               case ZEND_FETCH_OBJ_W:
+                                               case ZEND_FETCH_OBJ_RW:
+                                               case ZEND_FETCH_OBJ_FUNC_ARG:
+                                               case ZEND_ASSIGN_OBJ:
+                                               case ZEND_PRE_INC_OBJ:
+                                               case ZEND_PRE_DEC_OBJ:
+                                               case ZEND_POST_INC_OBJ:
+                                               case ZEND_POST_DEC_OBJ:
+                                                       tmp |= MAY_BE_ARRAY_OF_OBJECT;
                                                        break;
                                                case ZEND_SEND_VAR_EX:
                                                case ZEND_SEND_VAR_NO_REF:
                                                case ZEND_SEND_VAR_NO_REF_EX:
                                                case ZEND_SEND_REF:
                                                case ZEND_ASSIGN_REF:
-                                                       tmp |= MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
+                                               case ZEND_YIELD:
+                                               case ZEND_INIT_ARRAY:
+                                               case ZEND_ADD_ARRAY_ELEMENT:
+                                               case ZEND_RETURN_BY_REF:
+                                               case ZEND_VERIFY_RETURN_TYPE:
+                                                       tmp |= MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
                                                        break;
                                                case ZEND_PRE_INC:
                                                case ZEND_PRE_DEC:
@@ -3226,7 +3241,13 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                                                tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE;
                                                        }
                                                        break;
+                                               case ZEND_UNSET_DIM:
+                                               case ZEND_UNSET_OBJ:
+                                               case ZEND_FETCH_DIM_UNSET:
+                                               case ZEND_FETCH_OBJ_UNSET:
+                                                       break;
                                                default :
+                                                       ZEND_ASSERT(0);
                                                        break;
                                        }
                                        j = zend_ssa_next_use(ssa_ops, ssa_ops[i].result_def, j);
@@ -3368,6 +3389,11 @@ static void zend_update_type_info(const zend_op_array *op_array,
                        }
                        break;
                }
+               case ZEND_CATCH:
+               case ZEND_INCLUDE_OR_EVAL:
+                       /* Forbidden opcodes */
+                       ZEND_ASSERT(0);
+                       break;
                default:
 unknown_opcode:
                        if (ssa_ops[i].op1_def >= 0) {