Fix GH-8140: Wrong first class callable by name optimization

When optimizing by name function calls, we must not replace
`CALLABLE_CONVERT` opcodes, but have to keep them.

Closes GH-8144.
This commit is contained in:
Christoph M. Becker 2022-02-23 14:14:46 +01:00
parent 5d907dfcee
commit 33cd61c904
No known key found for this signature in database
GPG Key ID: D66C9593118BCCB6
4 changed files with 37 additions and 2 deletions

1
NEWS
View File

@ -9,6 +9,7 @@ PHP NEWS
variables. (ilutov)
. Fixed bug GH-7958 (Nested CallbackFilterIterator is leaking memory). (cmb)
. Fixed bug GH-8074 (Wrong type inference of range() result). (cmb)
. Fixed bug GH-8140 (Wrong first class callable by name optimization). (cmb)
- GD:
. Fixed libpng warning when loading interlaced images. (Brett)

View File

@ -200,14 +200,18 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&ZEND_OP2_LITERAL(fcall));
fcall->op2.constant = fcall->op2.constant + 1;
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
}
} else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
fcall->opcode = ZEND_INIT_FCALL;
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&op_array->literals[fcall->op2.constant]);
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
fcall->op2.constant = fcall->op2.constant + 1;
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
}
} else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
|| fcall->opcode == ZEND_INIT_METHOD_CALL
|| fcall->opcode == ZEND_NEW) {

View File

@ -0,0 +1,16 @@
--TEST--
GH-8140 (Wrong first class callable by name optimization)
--FILE--
<?php
namespace Test;
function greeter(string $name) {
echo "Hello, ${name}!";
}
$mycallable = greeter(...);
$mycallable("world");
?>
--EXPECT--
Hello, world!

View File

@ -0,0 +1,14 @@
--TEST--
GH-8140 (Wrong first class callable by name optimization)
--FILE--
<?php
$mycallable = greeter(...);
function greeter(string $name) {
echo "Hello, ${name}!";
}
$mycallable("world");
?>
--EXPECT--
Hello, world!