From 41c84787bf481044b9bc614696a7de7c05ec86bb Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 7 Apr 2026 20:31:15 -0400 Subject: [PATCH] Fix GH-17144: type inference narrowing on ZEND_FETCH_DIM_W FETCH_DIM_W stripped MAY_BE_ARRAY_EMPTY only when key_type had valid key bits. When the key operand's type widened across loop iterations (from MAY_BE_ARRAY to include scalar types), key_type transitioned from 0 to non-zero, causing MAY_BE_ARRAY_EMPTY to be stripped on the second pass but not the first. This violated monotonicity. Strip MAY_BE_ARRAY_EMPTY for write opcodes (W, RW, LIST_W) regardless of key_type, since a dimension write makes the array non-empty. Closes GH-17144 --- Zend/Optimizer/zend_inference.c | 5 +++++ Zend/tests/gh17144.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 Zend/tests/gh17144.phpt diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index f0d8d873977e2..f03999aa114ec 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -3719,6 +3719,11 @@ static zend_always_inline zend_result _zend_update_type_info( if (opline->opcode != ZEND_FETCH_DIM_FUNC_ARG) { tmp &= ~MAY_BE_ARRAY_EMPTY; } + } else if ((opline->opcode == ZEND_FETCH_DIM_W + || opline->opcode == ZEND_FETCH_DIM_RW + || opline->opcode == ZEND_FETCH_LIST_W) + && (tmp & MAY_BE_ARRAY)) { + tmp &= ~MAY_BE_ARRAY_EMPTY; } if (!(tmp & MAY_BE_ARRAY) || (tmp & MAY_BE_ARRAY_KEY_ANY) diff --git a/Zend/tests/gh17144.phpt b/Zend/tests/gh17144.phpt new file mode 100644 index 0000000000000..2c394a14fac4d --- /dev/null +++ b/Zend/tests/gh17144.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-17144 (Assertion failure during type inference of ZEND_FETCH_DIM_W) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1254 +--EXTENSIONS-- +opcache +--FILE-- + 1, + ]; + } +} +echo "Done\n"; +?> +--EXPECT-- +Done