case ZEND_FETCH_OBJ_UNSET:
case ZEND_FETCH_OBJ_FUNC_ARG:
if (ssa_op->result_def >= 0) {
- tmp = zend_fetch_prop_type(script,
- zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce);
+ zend_property_info *prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
+
+ tmp = zend_fetch_prop_type(script, prop_info, &ce);
if (opline->result_type != IS_TMP_VAR) {
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
+ } else if (prop_info) {
+ /* FETCH_OBJ_R/IS for plain property increments reference counter,
+ so it can't be 1 */
+ tmp &= ~MAY_BE_RC1;
+ } else {
+ zend_class_entry *ce = NULL;
+
+ if (opline->op1_type == IS_UNUSED) {
+ ce = op_array->scope;
+ } else if (ssa_op->op1_use >= 0 && !ssa->var_info[ssa_op->op1_use].is_instanceof) {
+ ce = ssa->var_info[ssa_op->op1_use].ce;
+ }
+ if (ce && !ce->create_object && !ce->__get) {
+ tmp &= ~MAY_BE_RC1;
+ }
}
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
if (ce) {
zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce);
if (opline->result_type != IS_TMP_VAR) {
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
+ } else {
+ tmp &= ~MAY_BE_RC1;
}
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
if (ce) {
if (ssa_op->result_def >= 0) {
tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
if (opline->result_type == IS_TMP_VAR) {
- tmp |= MAY_BE_RC1 | MAY_BE_RCN;
+ if (opline->opcode == ZEND_FETCH_R || opline->opcode == ZEND_FETCH_IS) {
+ tmp |= MAY_BE_RCN;
+ } else {
+ tmp |= MAY_BE_RC1 | MAY_BE_RCN;
+ }
} else {
tmp |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN;
switch (opline->opcode) {