Skip to content

Commit 4ae483a

Browse files
committed
Fixed selection candidates for register allocation
Fixea oss-fuzz #63545
1 parent 0493842 commit 4ae483a

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5559,29 +5559,35 @@ static int zend_jit_long_math_helper(zend_jit_ctx *jit,
55595559
}
55605560

55615561
if (op1_info & MAY_BE_UNDEF) {
5562-
ir_ref if_def;
5562+
ir_ref if_def, ref, ref2;
55635563

5564+
ref = jit_ZVAL_ADDR(jit, op1_addr);
55645565
if_def = jit_if_not_Z_TYPE(jit, op1_addr, IS_UNDEF);
55655566
ir_IF_FALSE_cold(if_def);
55665567

55675568
// zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var))));
55685569
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_op_helper), ir_CONST_U32(opline->op1.var));
55695570

5570-
jit_set_Z_TYPE_INFO(jit, op1_addr, IS_NULL);
5571+
ref2 = jit_EG(uninitialized_zval);
55715572
ir_MERGE_WITH_EMPTY_TRUE(if_def);
5573+
ref = ir_PHI_2(IR_ADDR, ref2, ref);
5574+
op1_addr = ZEND_ADDR_REF_ZVAL(ref);
55725575
}
55735576

55745577
if (op2_info & MAY_BE_UNDEF) {
5575-
ir_ref if_def;
5578+
ir_ref if_def, ref, ref2;
55765579

5580+
ref = jit_ZVAL_ADDR(jit, op2_addr);
55775581
if_def = jit_if_not_Z_TYPE(jit, op2_addr, IS_UNDEF);
55785582
ir_IF_FALSE_cold(if_def);
55795583

55805584
// zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op2.var))));
55815585
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_op_helper), ir_CONST_U32(opline->op2.var));
55825586

5583-
jit_set_Z_TYPE_INFO(jit, op2_addr, IS_NULL);
5587+
ref2 = jit_EG(uninitialized_zval);
55845588
ir_MERGE_WITH_EMPTY_TRUE(if_def);
5589+
ref = ir_PHI_2(IR_ADDR, ref2, ref);
5590+
op2_addr = ZEND_ADDR_REF_ZVAL(ref);
55855591
}
55865592

55875593
if (Z_MODE(op1_addr) == IS_REG) {
@@ -16327,6 +16333,15 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
1632716333
case ZEND_MUL:
1632816334
op1_info = OP1_INFO();
1632916335
op2_info = OP2_INFO();
16336+
if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
16337+
return 0;
16338+
}
16339+
if (trace && trace->op1_type != IS_UNKNOWN) {
16340+
op1_info &= 1U << (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED));
16341+
}
16342+
if (trace && trace->op2_type != IS_UNKNOWN) {
16343+
op2_info &= 1U << (trace->op2_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED));
16344+
}
1633016345
return !(op1_info & MAY_BE_UNDEF)
1633116346
&& !(op2_info & MAY_BE_UNDEF)
1633216347
&& (op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE))
@@ -16339,6 +16354,12 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
1633916354
case ZEND_MOD:
1634016355
op1_info = OP1_INFO();
1634116356
op2_info = OP2_INFO();
16357+
if (trace && trace->op1_type != IS_UNKNOWN) {
16358+
op1_info &= 1U << (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED));
16359+
}
16360+
if (trace && trace->op2_type != IS_UNKNOWN) {
16361+
op2_info &= 1U << (trace->op2_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED));
16362+
}
1634216363
return (op1_info & MAY_BE_LONG)
1634316364
&& (op2_info & MAY_BE_LONG);
1634416365
case ZEND_PRE_INC:
@@ -16384,6 +16405,13 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
1638416405
&& (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)) == IS_ARRAY) {
1638516406
op1_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY);
1638616407
}
16408+
if (trace && trace->op2_type != IS_UNKNOWN) {
16409+
if ((trace->op2_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)) == IS_LONG) {
16410+
op2_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_LONG);
16411+
} else if ((trace->op2_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)) == IS_STRING) {
16412+
op2_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_STRING);
16413+
}
16414+
}
1638716415
return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&
1638816416
(!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || !(op1_info & MAY_BE_RC1)) &&
1638916417
(((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) ||
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Register Alloction 018: Incorrect allocation
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
6 & $y & 6 & $y;
11+
?>
12+
DONE
13+
--EXPECTF--
14+
Warning: Undefined variable $y in %sreg_alloc_018.php on line 2
15+
16+
Warning: Undefined variable $y in %sreg_alloc_018.php on line 2
17+
DONE

0 commit comments

Comments
 (0)