diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 92a068dbfaca..0696dd3ea4ad 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -15988,15 +15988,22 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_ if (opline->op1_type == IS_CONST) { zval *zv = RT_CONSTANT(opline, opline->op1); zval *jump_zv = NULL; + const zend_op *target; int b; + /* Wrong type for SWITCH_LONG/SWITCH_STRING falls back to the ZEND_CASE chain */ + target = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); if (opline->opcode == ZEND_SWITCH_LONG) { if (Z_TYPE_P(zv) == IS_LONG) { jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(zv)); + } else { + target = opline + 1; } } else if (opline->opcode == ZEND_SWITCH_STRING) { if (Z_TYPE_P(zv) == IS_STRING) { jump_zv = zend_hash_find_known_hash(jumptable, Z_STR_P(zv)); + } else { + target = opline + 1; } } else if (opline->opcode == ZEND_MATCH) { if (Z_TYPE_P(zv) == IS_LONG) { @@ -16007,21 +16014,13 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_ } else { ZEND_UNREACHABLE(); } + if (jump_zv != NULL) { + target = ZEND_OFFSET_TO_OPLINE(opline, Z_LVAL_P(jump_zv)); + } if (next_opline) { - const zend_op *target; - - if (jump_zv != NULL) { - target = ZEND_OFFSET_TO_OPLINE(opline, Z_LVAL_P(jump_zv)); - } else { - target = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } ZEND_ASSERT(target == next_opline); } else { - if (jump_zv != NULL) { - b = ssa->cfg.map[ZEND_OFFSET_TO_OPLINE(opline, Z_LVAL_P(jump_zv)) - op_array->opcodes]; - } else { - b = ssa->cfg.map[ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) - op_array->opcodes]; - } + b = ssa->cfg.map[target - op_array->opcodes]; _zend_jit_add_predecessor_ref(jit, b, jit->b, ir_END()); jit->b = -1; } diff --git a/ext/opcache/tests/jit/gh24391.phpt b/ext/opcache/tests/jit/gh24391.phpt new file mode 100644 index 000000000000..abad5408e5d0 --- /dev/null +++ b/ext/opcache/tests/jit/gh24391.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-24391 (JIT: switch on constant of wrong type takes default instead of falling back to the case chain) +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=function +opcache.optimization_level=0 +--FILE-- + +--EXPECT-- +int(1) +int(6)