@@ -2085,6 +2085,41 @@ ZEND_API uint32_t zend_array_element_type(uint32_t t1, zend_uchar op_type, int w
2085
2085
return tmp ;
2086
2086
}
2087
2087
2088
+ static uint32_t assign_dim_array_result_type (
2089
+ uint32_t arr_type , uint32_t dim_type , uint32_t value_type , zend_uchar dim_op_type ) {
2090
+ uint32_t tmp = 0 ;
2091
+ /* Only add key type if we have a value type. We want to maintain the invariant that a
2092
+ * key type exists iff a value type exists even in dead code that may use empty types. */
2093
+ if (value_type & (MAY_BE_ANY |MAY_BE_UNDEF )) {
2094
+ if (value_type & MAY_BE_UNDEF ) {
2095
+ value_type |= MAY_BE_NULL ;
2096
+ }
2097
+ if (dim_op_type == IS_UNUSED ) {
2098
+ tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
2099
+ } else {
2100
+ if (dim_type & (MAY_BE_LONG |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_RESOURCE |MAY_BE_DOUBLE )) {
2101
+ tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
2102
+ }
2103
+ if (dim_type & MAY_BE_STRING ) {
2104
+ tmp |= MAY_BE_ARRAY_KEY_STRING ;
2105
+ if (dim_op_type != IS_CONST ) {
2106
+ // FIXME: numeric string
2107
+ tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
2108
+ }
2109
+ }
2110
+ if (dim_type & (MAY_BE_UNDEF |MAY_BE_NULL )) {
2111
+ tmp |= MAY_BE_ARRAY_KEY_STRING ;
2112
+ }
2113
+ }
2114
+ }
2115
+ /* Only add value type if we have a key type. It might be that the key type is illegal
2116
+ * for arrays. */
2117
+ if (tmp & MAY_BE_ARRAY_KEY_ANY ) {
2118
+ tmp |= (value_type & MAY_BE_ANY ) << MAY_BE_ARRAY_SHIFT ;
2119
+ }
2120
+ return tmp ;
2121
+ }
2122
+
2088
2123
static uint32_t assign_dim_result_type (
2089
2124
uint32_t arr_type , uint32_t dim_type , uint32_t value_type , zend_uchar dim_op_type ) {
2090
2125
uint32_t tmp = arr_type & ~(MAY_BE_RC1 |MAY_BE_RCN );
@@ -2100,35 +2135,7 @@ static uint32_t assign_dim_result_type(
2100
2135
tmp |= MAY_BE_RC1 | MAY_BE_RCN ;
2101
2136
}
2102
2137
if (tmp & MAY_BE_ARRAY ) {
2103
- /* Only add key type if we have a value type. We want to maintain the invariant that a
2104
- * key type exists iff a value type exists even in dead code that may use empty types. */
2105
- if (value_type & (MAY_BE_ANY |MAY_BE_UNDEF )) {
2106
- if (value_type & MAY_BE_UNDEF ) {
2107
- value_type |= MAY_BE_NULL ;
2108
- }
2109
- if (dim_op_type == IS_UNUSED ) {
2110
- tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
2111
- } else {
2112
- if (dim_type & (MAY_BE_LONG |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_RESOURCE |MAY_BE_DOUBLE )) {
2113
- tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
2114
- }
2115
- if (dim_type & MAY_BE_STRING ) {
2116
- tmp |= MAY_BE_ARRAY_KEY_STRING ;
2117
- if (dim_op_type != IS_CONST ) {
2118
- // FIXME: numeric string
2119
- tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
2120
- }
2121
- }
2122
- if (dim_type & (MAY_BE_UNDEF |MAY_BE_NULL )) {
2123
- tmp |= MAY_BE_ARRAY_KEY_STRING ;
2124
- }
2125
- }
2126
- }
2127
- /* Only add value type if we have a key type. It might be that the key type is illegal
2128
- * for arrays. */
2129
- if (tmp & MAY_BE_ARRAY_KEY_ANY ) {
2130
- tmp |= (value_type & MAY_BE_ANY ) << MAY_BE_ARRAY_SHIFT ;
2131
- }
2138
+ tmp |= assign_dim_array_result_type (arr_type , dim_type , value_type , dim_op_type );
2132
2139
}
2133
2140
return tmp ;
2134
2141
}
@@ -3181,41 +3188,17 @@ static zend_always_inline int _zend_update_type_info(
3181
3188
}
3182
3189
if (ssa_op -> result_def >= 0 ) {
3183
3190
uint32_t arr_type ;
3184
-
3185
3191
if (opline -> opcode == ZEND_INIT_ARRAY ) {
3186
3192
arr_type = 0 ;
3187
3193
} else {
3188
3194
arr_type = RES_USE_INFO ();
3189
3195
}
3190
- tmp = MAY_BE_RC1 |MAY_BE_ARRAY ;
3191
- if (ssa_op -> result_use >= 0 ) {
3192
- tmp |= ssa_var_info [ssa_op -> result_use ].type ;
3193
- }
3196
+ tmp = MAY_BE_RC1 |MAY_BE_ARRAY |arr_type ;
3194
3197
if (opline -> op1_type != IS_UNUSED ) {
3195
- tmp |= (t1 & MAY_BE_ANY ) << MAY_BE_ARRAY_SHIFT ;
3196
- if (t1 & MAY_BE_UNDEF ) {
3197
- tmp |= MAY_BE_ARRAY_OF_NULL ;
3198
- }
3198
+ tmp |= assign_dim_array_result_type (arr_type , t2 , t1 , opline -> op2_type );
3199
3199
if (opline -> extended_value & ZEND_ARRAY_ELEMENT_REF ) {
3200
3200
tmp |= MAY_BE_ARRAY_OF_ANY |MAY_BE_ARRAY_OF_REF ;
3201
3201
}
3202
- if (opline -> op2_type == IS_UNUSED ) {
3203
- tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
3204
- } else {
3205
- if (t2 & (MAY_BE_LONG |MAY_BE_FALSE |MAY_BE_TRUE |MAY_BE_DOUBLE |MAY_BE_RESOURCE )) {
3206
- tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
3207
- }
3208
- if (t2 & (MAY_BE_STRING )) {
3209
- tmp |= MAY_BE_ARRAY_KEY_STRING ;
3210
- if (opline -> op2_type != IS_CONST ) {
3211
- // FIXME: numeric string
3212
- tmp |= MAY_BE_HASH_ONLY (arr_type ) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG ;
3213
- }
3214
- }
3215
- if (t2 & (MAY_BE_UNDEF | MAY_BE_NULL )) {
3216
- tmp |= MAY_BE_ARRAY_KEY_STRING ;
3217
- }
3218
- }
3219
3202
}
3220
3203
UPDATE_SSA_TYPE (tmp , ssa_op -> result_def );
3221
3204
}
0 commit comments