Skip to content

Commit 348386c

Browse files
committed
Fix RC inference for INIT_METHOD_CALL
1 parent 530ce37 commit 348386c

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

Zend/Optimizer/zend_inference.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3926,6 +3926,16 @@ static zend_always_inline zend_result _zend_update_type_info(
39263926
}
39273927
}
39283928
break;
3929+
case ZEND_INIT_METHOD_CALL:
3930+
if (ssa_op->op1_def >= 0) {
3931+
tmp = t1;
3932+
if (tmp & (MAY_BE_RC1|MAY_BE_RCN)) {
3933+
tmp |= (MAY_BE_RC1|MAY_BE_RCN);
3934+
}
3935+
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
3936+
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
3937+
}
3938+
break;
39293939
case ZEND_CALLABLE_CONVERT:
39303940
UPDATE_SSA_TYPE(MAY_BE_OBJECT | MAY_BE_RC1 | MAY_BE_RCN, ssa_op->result_def);
39313941
UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);

Zend/Optimizer/zend_ssa.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,11 @@ static zend_always_inline int _zend_ssa_rename_op(const zend_op_array *op_array,
806806
goto add_op1_def;
807807
}
808808
break;
809+
case ZEND_INIT_METHOD_CALL:
810+
if ((build_flags & ZEND_SSA_RC_INFERENCE) && (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR))) {
811+
goto add_op1_def;
812+
}
813+
break;
809814
default:
810815
break;
811816
}

ext/opcache/jit/zend_jit_ir.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6539,14 +6539,20 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit,
65396539
}
65406540
counter = jit_GC_DELREF(jit, ref);
65416541

6542-
if_not_zero = ir_IF(counter);
6543-
ir_IF_FALSE(if_not_zero);
6544-
jit_ZVAL_DTOR(jit, ref, var_info, opline);
6545-
if (check_exception) {
6546-
zend_jit_check_exception(jit);
6542+
if (RC_MAY_BE_1(var_info) && RC_MAY_BE_N(var_info)) {
6543+
if_not_zero = ir_IF(counter);
6544+
ir_IF_FALSE(if_not_zero);
6545+
}
6546+
if (RC_MAY_BE_1(var_info)) {
6547+
jit_ZVAL_DTOR(jit, ref, var_info, opline);
6548+
if (check_exception) {
6549+
zend_jit_check_exception(jit);
6550+
}
6551+
}
6552+
if (RC_MAY_BE_1(var_info) && RC_MAY_BE_N(var_info)) {
6553+
ir_refs_add(end_inputs, ir_END());
6554+
ir_IF_TRUE(if_not_zero);
65476555
}
6548-
ir_refs_add(end_inputs, ir_END());
6549-
ir_IF_TRUE(if_not_zero);
65506556
if (RC_MAY_BE_N(var_info) && (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0) {
65516557
ir_ref if_may_leak = jit_if_GC_MAY_NOT_LEAK(jit, ref);
65526558
ir_IF_FALSE(if_may_leak);

ext/opcache/tests/jit/gh17152_3.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
GH-17151: Method calls may modify RC of ZEND_INIT_METHOD_CALL op1
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public static $prop;
8+
9+
public function storeThis() {
10+
self::$prop = $this;
11+
}
12+
}
13+
14+
function test() {
15+
$c = new C();
16+
$c->storeThis();
17+
$c = null;
18+
}
19+
20+
test();
21+
22+
?>
23+
===DONE===
24+
--EXPECT--
25+
===DONE===

0 commit comments

Comments
 (0)