Skip to content

Commit 4dc669a

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Don't optimize trailing args for prototype fbc
2 parents d87ba95 + 11f950e commit 4dc669a

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

Zend/Optimizer/optimize_func_calls.c

+18-4
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
139139
}
140140
}
141141

142+
/* arg_num is 1-based here, to match SEND encoding. */
143+
static bool has_known_send_mode(const optimizer_call_info *info, uint32_t arg_num)
144+
{
145+
if (!info->func) {
146+
return false;
147+
}
148+
149+
/* For prototype functions we should not make assumptions about arguments that are not part of
150+
* the signature: And inheriting method can add an optional by-ref argument. */
151+
return !info->is_prototype
152+
|| arg_num <= info->func->common.num_args
153+
|| (info->func->common.fn_flags & ZEND_ACC_VARIADIC);
154+
}
155+
142156
void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
143157
{
144158
zend_op *opline = op_array->opcodes;
@@ -251,7 +265,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
251265
}
252266
break;
253267
case ZEND_SEND_VAL_EX:
254-
if (call_stack[call - 1].func) {
268+
if (has_known_send_mode(&call_stack[call - 1], opline->op2.num)) {
255269
if (opline->op2_type == IS_CONST) {
256270
call_stack[call - 1].try_inline = 0;
257271
break;
@@ -266,7 +280,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
266280
}
267281
break;
268282
case ZEND_CHECK_FUNC_ARG:
269-
if (call_stack[call - 1].func) {
283+
if (has_known_send_mode(&call_stack[call - 1], opline->op2.num)) {
270284
if (opline->op2_type == IS_CONST) {
271285
call_stack[call - 1].try_inline = 0;
272286
call_stack[call - 1].func_arg_num = (uint32_t)-1;
@@ -279,7 +293,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
279293
break;
280294
case ZEND_SEND_VAR_EX:
281295
case ZEND_SEND_FUNC_ARG:
282-
if (call_stack[call - 1].func) {
296+
if (has_known_send_mode(&call_stack[call - 1], opline->op2.num)) {
283297
if (opline->op2_type == IS_CONST) {
284298
call_stack[call - 1].try_inline = 0;
285299
break;
@@ -294,7 +308,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
294308
}
295309
break;
296310
case ZEND_SEND_VAR_NO_REF_EX:
297-
if (call_stack[call - 1].func) {
311+
if (has_known_send_mode(&call_stack[call - 1], opline->op2.num)) {
298312
if (opline->op2_type == IS_CONST) {
299313
call_stack[call - 1].try_inline = 0;
300314
break;
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Adding an optional by-ref arg in a child method
3+
--FILE--
4+
<?php
5+
6+
class Test1 {
7+
public function method1() {
8+
$this->method2($x);
9+
var_dump($x);
10+
}
11+
public function method2() {}
12+
}
13+
class Test2 extends Test1 {
14+
public function method2(&$x = null) {
15+
++$x;
16+
}
17+
}
18+
(new Test2)->method1();
19+
20+
?>
21+
--EXPECT--
22+
int(1)

0 commit comments

Comments
 (0)