Fix GH-17144: type inference narrowing on ZEND_FETCH_DIM_W#21674
Open
iliaal wants to merge 1 commit intophp:PHP-8.4from
Open
Fix GH-17144: type inference narrowing on ZEND_FETCH_DIM_W#21674iliaal wants to merge 1 commit intophp:PHP-8.4from
iliaal wants to merge 1 commit intophp:PHP-8.4from
Conversation
41c8478 to
cb5269e
Compare
dstogov
reviewed
Apr 13, 2026
Member
dstogov
left a comment
There was a problem hiding this comment.
This solution looks completely wrong.
The following PHP code doesn't modify $a (it throws exception) and $a is still empty.
$a = [];
$a[$a] = 1;FETCH_DIM_W stripped MAY_BE_ARRAY_EMPTY when key_type had any valid key bit set. As the key operand's type widened across iterations (e.g. from MAY_BE_ARRAY to MAY_BE_ARRAY|MAY_BE_LONG), key_type transitioned from 0 to non-zero, flipping the strip from inactive to active. The resulting type lost MAY_BE_ARRAY_EMPTY mid-iteration, tripping the narrowing assertion. Stripping unconditionally is unsound: $a = []; $a[$a] = 1; throws before the write, leaving the array empty. Strip only when the key operand is guaranteed a valid array key, i.e. when op2 is IS_UNUSED (append) or t2 contains no MAY_BE_ARRAY or MAY_BE_OBJECT bits. As t2 widens, this condition can only flip from true to false, so the result type monotonically gains MAY_BE_ARRAY_EMPTY back rather than losing it. Test covers both the original narrowing reproducer and the invalid-key throw path. Closes phpGH-17144
cb5269e to
f6f5b5b
Compare
Contributor
Author
|
Confirmed: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FETCH_DIM_WstrippedMAY_BE_ARRAY_EMPTYonly inside a block guarded bykey_type & (MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING). When the key operand's type widened across loop iterations (e.g. fromMAY_BE_ARRAYto include scalar types),key_typewent from 0 to non-zero, causing the flag to be stripped on the second pass but not the first. This violated monotonicity and triggered the narrowing assertion.Strips
MAY_BE_ARRAY_EMPTYfor write opcodes (W, RW, LIST_W) regardless ofkey_type, since a dimension write makes the array non-empty.Fixes #17144