zend_error(E_WARNING, "Narrowing occurred during type inference of %s. Please file a bug report on bugs.php.net", def_op_name);
}
-uint32_t zend_array_element_type(uint32_t t1, int write, int insert)
+uint32_t zend_array_element_type(uint32_t t1, zend_uchar op_type, int write, int insert)
{
uint32_t tmp = 0;
if (tmp & MAY_BE_ARRAY) {
tmp |= MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
}
- if (t1 & MAY_BE_ARRAY_OF_REF) {
+ if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
if (!write) {
/* can't be REF because of ZVAL_COPY_DEREF() usage */
- tmp |= MAY_BE_RC1 | MAY_BE_RCN;
- } else {
+ tmp |= MAY_BE_RCN;
+ if ((op_type & (IS_VAR|IS_TMP_VAR)) && (t1 & MAY_BE_RC1)) {
+ tmp |= MAY_BE_RC1;
+ }
+ } else if (t1 & MAY_BE_ARRAY_OF_REF) {
tmp |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN;
+ } else {
+ tmp |= MAY_BE_RC1 | MAY_BE_RCN;
}
- } else if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
- tmp |= MAY_BE_RC1 | MAY_BE_RCN;
}
}
if (write) {
tmp |= MAY_BE_REF;
}
orig = t1;
- t1 = zend_array_element_type(t1, 1, 0);
+ t1 = zend_array_element_type(t1, opline->op1_type, 1, 0);
t2 = OP1_DATA_INFO();
} else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline);
/* FETCH_LIST on a string behaves like FETCH_R on null */
tmp = zend_array_element_type(
opline->opcode != ZEND_FETCH_LIST_R ? t1 : ((t1 & ~MAY_BE_STRING) | MAY_BE_NULL),
+ opline->op1_type,
opline->result_type == IS_VAR,
opline->op2_type == IS_UNUSED);
if (opline->opcode == ZEND_FETCH_DIM_IS && (t1 & MAY_BE_STRING)) {
int zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa);
int zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_long optimization_level);
-uint32_t zend_array_element_type(uint32_t t1, int write, int insert);
+uint32_t zend_array_element_type(uint32_t t1, zend_uchar op_type, int write, int insert);
int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int var, int widening, int narrowing, zend_ssa_range *tmp);
void zend_inference_init_range(const zend_op_array *op_array, zend_ssa *ssa, int var, zend_bool underflow, zend_long min, zend_long max, zend_bool overflow);
return 0;
}
} else {
- uint32_t var_info = zend_array_element_type(op1_info, 0, 0);
+ uint32_t var_info = zend_array_element_type(op1_info, opline->op1_type, 0, 0);
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, 8, 8, NULL, NULL)) {
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
var_info |= MAY_BE_REF;
}
+ if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
+ var_info |= MAY_BE_RC1;
+ }
| // value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
if (!zend_jit_assign_to_variable(Dst, opline, op_array, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
return 0;
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY)) {
uint32_t var_info;
- uint32_t var_def_info = zend_array_element_type(op1_def_info, 1, 0);
+ uint32_t var_def_info = zend_array_element_type(op1_def_info, opline->op1_type, 1, 0);
|6:
if (opline->op2_type == IS_UNUSED) {
|.code
| mov FCARG1a, r0
} else {
- var_info = zend_array_element_type(op1_info, 0, 0);
+ var_info = zend_array_element_type(op1_info, opline->op1_type, 0, 0);
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
var_info |= MAY_BE_REF;
}
+ if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
+ var_info |= MAY_BE_RC1;
+ }
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, 8, 8, NULL, NULL)) {
return 0;
|9: // END
if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) {
if (opline->op1_type == IS_VAR
- && opline->opcode == ZEND_FETCH_OBJ_W) {
+ && opline->opcode == ZEND_FETCH_OBJ_W
+ && (op1_info & MAY_BE_RC1)) {
zend_jit_addr orig_op1_addr = OP1_ADDR();
| IF_NOT_ZVAL_REFCOUNTED orig_op1_addr, >1