Skip to content

Commit

Permalink
Fix RC tracking of op1 of FETCH_OBJ
Browse files Browse the repository at this point in the history
  • Loading branch information
iluuu1994 committed Dec 13, 2024
1 parent 07cd468 commit 4f5a6a3
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 0 deletions.
30 changes: 30 additions & 0 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -3767,6 +3767,36 @@ static zend_always_inline zend_result _zend_update_type_info(
case ZEND_FETCH_OBJ_W:
case ZEND_FETCH_OBJ_UNSET:
case ZEND_FETCH_OBJ_FUNC_ARG:
if (ssa_op->op1_def >= 0) {
tmp = t1;
if (tmp & (MAY_BE_RC1|MAY_BE_RCN)) {
do {
const 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;
}

// FIXME: Could be more permissive by checking for corresponding bp type,
// handler, hook and magic method.
if (ce
&& !ce->create_object
&& ce->default_object_handlers == &std_object_handlers) {
const zend_property_info *prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
if ((prop_info && !prop_info->hooks)
|| (!ce->__get && !ce->__set && !ce->__isset && !ce->__unset)) {
break;
}
}

tmp |= (MAY_BE_RC1|MAY_BE_RCN);
} while (0);
}
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
}
if (ssa_op->result_def >= 0) {
uint32_t tmp = 0;
ce = NULL;
Expand Down
11 changes: 11 additions & 0 deletions Zend/Optimizer/zend_ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,18 @@ static zend_always_inline int _zend_ssa_rename_op(const zend_op_array *op_array,
}
}
}
break;
}
case ZEND_FETCH_OBJ_R:
case ZEND_FETCH_OBJ_IS:
case ZEND_FETCH_OBJ_RW:
case ZEND_FETCH_OBJ_W:
case ZEND_FETCH_OBJ_UNSET:
case ZEND_FETCH_OBJ_FUNC_ARG:
if ((build_flags & ZEND_SSA_RC_INFERENCE) && (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR))) {
goto add_op1_def;
}
break;
default:
break;
}
Expand Down
3 changes: 3 additions & 0 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -14591,6 +14591,9 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
if (on_this) {
op1_info &= ~MAY_BE_RC1;
}
if (ssa_op->op1_def >= 0) {
op1_info |= (ssa->var_info[ssa_op->op1_def].type & (MAY_BE_RC1|MAY_BE_RCN));
}
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
}
}
Expand Down
22 changes: 22 additions & 0 deletions ext/opcache/tests/jit/gh17151_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GH-17151: ZEND_FETCH_OBJ_R may modify RC of op1
--FILE--
<?php

class C {
public function __get($name) {
return $this;
}
}

function test() {
$x = (new C)->bar;
var_dump($x);
}

test();

?>
--EXPECTF--
object(C)#%d (0) {
}
29 changes: 29 additions & 0 deletions ext/opcache/tests/jit/gh17151_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
GH-17151: ZEND_FETCH_OBJ_R may modify RC of op1
--FILE--
<?php

class C {
public static $prop;

public function __get($name) {
C::$prop = null;
}

public function __destruct() {
echo __METHOD__, "\n";
}
}

function test() {
C::$prop = new C();
C::$prop->bar;
}

test();
echo "Done\n";

?>
--EXPECT--
C::__destruct
Done

0 comments on commit 4f5a6a3

Please sign in to comment.