Skip to content

Commit 93d5c0e

Browse files
committed
Fixed missed type store
1 parent 06b009c commit 93d5c0e

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4893,6 +4893,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
48934893
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info))) {
48944894
goto jit_failure;
48954895
}
4896+
if (ssa_op->op2_def > 0
4897+
&& Z_MODE(op2_addr) == IS_REG
4898+
&& ssa->vars[ssa_op->op2_def].no_val) {
4899+
uint8_t type = (op2_info & MAY_BE_LONG) ? IS_LONG : IS_DOUBLE;
4900+
uint32_t var_num = EX_VAR_TO_NUM(opline->op2.var);
4901+
4902+
if (STACK_MEM_TYPE(stack, var_num) != type
4903+
&& ssa->vars[ssa_op->op2_def].use_chain < 0
4904+
&& !ssa->vars[ssa_op->op2_def].phi_use_chain) {
4905+
if (!zend_jit_store_type(&ctx, var_num, type)) {
4906+
return 0;
4907+
}
4908+
SET_STACK_TYPE(stack, var_num, type, 1);
4909+
}
4910+
}
48964911
if (opline->op2_type == IS_CV
48974912
&& ssa_op->op2_def >= 0
48984913
&& ssa->vars[ssa_op->op2_def].alias == NO_ALIAS) {
@@ -4931,6 +4946,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49314946
res_use_info, res_info, res_addr)) {
49324947
goto jit_failure;
49334948
}
4949+
if (ssa_op->op1_def > 0
4950+
&& Z_MODE(op1_addr) == IS_REG
4951+
&& ssa->vars[ssa_op->op1_def].no_val) {
4952+
uint8_t type = (op1_info & MAY_BE_LONG) ? IS_LONG : IS_DOUBLE;
4953+
uint32_t var_num = EX_VAR_TO_NUM(opline->op1.var);
4954+
4955+
if (STACK_MEM_TYPE(stack, var_num) != type
4956+
&& ssa->vars[ssa_op->op1_def].use_chain < 0
4957+
&& !ssa->vars[ssa_op->op1_def].phi_use_chain) {
4958+
if (!zend_jit_store_type(&ctx, var_num, type)) {
4959+
return 0;
4960+
}
4961+
SET_STACK_TYPE(stack, var_num, type, 1);
4962+
}
4963+
}
49344964
if (opline->op1_type == IS_CV
49354965
&& ssa_op->op1_def >= 0
49364966
&& ssa->vars[ssa_op->op1_def].alias == NO_ALIAS) {
@@ -5013,6 +5043,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50135043
op1_info, op1_addr, op1_def_addr)) {
50145044
goto jit_failure;
50155045
}
5046+
if (ssa_op->op1_def > 0
5047+
&& Z_MODE(op1_addr) == IS_REG
5048+
&& ssa->vars[ssa_op->op1_def].no_val) {
5049+
uint8_t type = (op1_info & MAY_BE_LONG) ? IS_LONG : IS_DOUBLE;
5050+
uint32_t var_num = EX_VAR_TO_NUM(opline->op1.var);
5051+
5052+
if (STACK_MEM_TYPE(stack, var_num) != type
5053+
&& ssa->vars[ssa_op->op1_def].use_chain < 0
5054+
&& !ssa->vars[ssa_op->op1_def].phi_use_chain) {
5055+
if (!zend_jit_store_type(&ctx, var_num, type)) {
5056+
return 0;
5057+
}
5058+
SET_STACK_TYPE(stack, var_num, type, 1);
5059+
}
5060+
}
50165061
if (opline->op1_type == IS_CV
50175062
&& ssa_op->op1_def >= 0
50185063
&& ssa->vars[ssa_op->op1_def].alias == NO_ALIAS) {

ext/opcache/tests/jit/gh12512.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
GH-12512: missing type store
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
--FILE--
7+
<?php
8+
function bar(array &$a): ?bool {
9+
$ret = null;
10+
foreach ($a as $key => $val) {
11+
if ($val === 2) {
12+
unset($a[$key]);
13+
}
14+
}
15+
return $ret;
16+
}
17+
18+
function foo($a, bool $b): bool {
19+
if ($b) return true;
20+
$n2 = count($a);
21+
do {
22+
$n = $n2;
23+
$res = bar($a);
24+
$n2 = count($a);
25+
} while ($res === null && $n !== $n2);
26+
27+
if ($res === null && $n === 0) {
28+
return false;
29+
}
30+
return true;
31+
}
32+
33+
$a = [1,'a'=>5];
34+
bar($a);
35+
foo([1,'a'=>5], true);
36+
foo([1,'a'=>5], false);
37+
foo([2,'a'=>5], false);
38+
?>
39+
DONE
40+
--EXPECT--
41+
DONE

0 commit comments

Comments
 (0)