Skip to content

SCCP: Fold array_key_exists() with boolean and integral float keys - #25436

Merged
LamentXU123 merged 2 commits into
php:masterfrom
LamentXU123:sccpopt
Nov 13, 2026
Merged

LamentXU123 merged 2 commits into
php:masterfrom
LamentXU123:sccpopt

Conversation

@LamentXU123

Copy link
Copy Markdown
Member

We can remove the extra key-type restriction in ct_eval_array_key_exists() to allow SCCP to fold calls with boolean and integral float keys
This is safe because fetch_array_elem()

static inline zend_result fetch_array_elem(zval **result, const zval *op1, const zval *op2) {
switch (Z_TYPE_P(op2)) {
case IS_NULL:
return FAILURE;
case IS_FALSE:
*result = zend_hash_index_find(Z_ARR_P(op1), 0);
return SUCCESS;
case IS_TRUE:
*result = zend_hash_index_find(Z_ARR_P(op1), 1);
return SUCCESS;
case IS_LONG:
*result = zend_hash_index_find(Z_ARR_P(op1), Z_LVAL_P(op2));
return SUCCESS;
case IS_DOUBLE: {
zend_long lval = zend_dval_to_lval_silent(Z_DVAL_P(op2));
if (!zend_is_long_compatible(Z_DVAL_P(op2), lval)) {
return FAILURE;
}
*result = zend_hash_index_find(Z_ARR_P(op1), lval);
return SUCCESS;
}
case IS_STRING:
*result = zend_symtable_find(Z_ARR_P(op1), Z_STR_P(op2));
return SUCCESS;
default:
return FAILURE;
}
}

already implements the required conversions.

for example:

function test() {
    return array_key_exists(1.0, [1 => null]);
}

before

0000 T0 = ARRAY_KEY_EXISTS float(1) array(...)
0001 RETURN T0

after

0000 RETURN bool(true)

<?php
function test() {
var_dump(
array_key_exists(true, [1 => null]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test with NAN and null as the first argument, it must not be evaluated at compile time.

@LamentXU123

Copy link
Copy Markdown
Member Author

Thanks.

@LamentXU123
LamentXU123 merged commit 6fe61c8 into php:master Nov 13, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants