Skip to content

Commit 86cd009

Browse files
committed
Fix pass by ref error for named params
1 parent 2f9e9d4 commit 86cd009

File tree

3 files changed

+30
-23
lines changed

3 files changed

+30
-23
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Cannot pass by reference error with named parameters
3+
--FILE--
4+
<?php
5+
function test($a, &$e) {}
6+
try {
7+
test(e: 42);
8+
} catch (Error $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
?>
12+
--EXPECT--
13+
Cannot pass parameter 2 by reference

Zend/zend_vm_def.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4587,17 +4587,14 @@ ZEND_VM_HOT_HANDLER(65, ZEND_SEND_VAL, CONST|TMPVAR, CONST|UNUSED|NUM)
45874587
ZEND_VM_NEXT_OPCODE();
45884588
}
45894589

4590-
ZEND_VM_COLD_HELPER(zend_cannot_pass_by_ref_helper, ANY, ANY)
4590+
ZEND_VM_COLD_HELPER(zend_cannot_pass_by_ref_helper, ANY, ANY, uint32_t _arg_num, zval *_arg)
45914591
{
45924592
USE_OPLINE
4593-
zval *arg;
4594-
uint32_t arg_num = opline->op2.num;
45954593

45964594
SAVE_OPLINE();
4597-
zend_throw_error(NULL, "Cannot pass parameter %d by reference", arg_num);
4595+
zend_throw_error(NULL, "Cannot pass parameter %d by reference", _arg_num);
45984596
FREE_OP1();
4599-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4600-
ZVAL_UNDEF(arg);
4597+
ZVAL_UNDEF(_arg);
46014598
HANDLE_EXCEPTION();
46024599
}
46034600

@@ -4626,7 +4623,7 @@ ZEND_VM_HOT_SEND_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, CONST|UNUSED|NUM, SPE
46264623
}
46274624
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
46284625
ZEND_VM_C_LABEL(send_val_by_ref):
4629-
ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper);
4626+
ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper, _arg_num, arg_num, _arg, arg);
46304627
}
46314628
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
46324629
ZVAL_COPY_VALUE(arg, value);
@@ -9564,11 +9561,11 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAL_EX, op->op2_type == IS_UNUSED && op-
95649561
zval *value, *arg;
95659562
uint32_t arg_num = opline->op2.num;
95669563

9564+
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
95679565
if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
9568-
ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper);
9566+
ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper, _arg_num, arg_num, _arg, arg);
95699567
}
95709568
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
9571-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
95729569
ZVAL_COPY_VALUE(arg, value);
95739570
ZEND_VM_NEXT_OPCODE();
95749571
}

Zend/zend_vm_execute.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,17 +1837,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER(
18371837
}
18381838
}
18391839

1840-
static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
1840+
static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_cannot_pass_by_ref_helper_SPEC(uint32_t _arg_num, zval *_arg ZEND_OPCODE_HANDLER_ARGS_DC)
18411841
{
18421842
USE_OPLINE
1843-
zval *arg;
1844-
uint32_t arg_num = opline->op2.num;
18451843

18461844
SAVE_OPLINE();
1847-
zend_throw_error(NULL, "Cannot pass parameter %d by reference", arg_num);
1845+
zend_throw_error(NULL, "Cannot pass parameter %d by reference", _arg_num);
18481846
FREE_OP(opline->op1_type, opline->op1.var);
1849-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
1850-
ZVAL_UNDEF(arg);
1847+
ZVAL_UNDEF(_arg);
18511848
HANDLE_EXCEPTION();
18521849
}
18531850

@@ -4727,11 +4724,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SIMPLE
47274724
zval *value, *arg;
47284725
uint32_t arg_num = opline->op2.num;
47294726

4727+
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
47304728
if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
4731-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
4729+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
47324730
}
47334731
value = RT_CONSTANT(opline, opline->op1);
4734-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
47354732
ZVAL_COPY_VALUE(arg, value);
47364733
ZEND_VM_NEXT_OPCODE();
47374734
}
@@ -6115,7 +6112,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_CONST_H
61156112
}
61166113
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
61176114
send_val_by_ref:
6118-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
6115+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
61196116
}
61206117
value = RT_CONSTANT(opline, opline->op1);
61216118
ZVAL_COPY_VALUE(arg, value);
@@ -9151,7 +9148,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_
91519148
}
91529149
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
91539150
send_val_by_ref:
9154-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
9151+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
91559152
}
91569153
value = RT_CONSTANT(opline, opline->op1);
91579154
ZVAL_COPY_VALUE(arg, value);
@@ -9188,7 +9185,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_C
91889185
}
91899186
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
91909187
send_val_by_ref:
9191-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
9188+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
91929189
}
91939190
value = RT_CONSTANT(opline, opline->op1);
91949191
ZVAL_COPY_VALUE(arg, value);
@@ -18631,7 +18628,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HAN
1863118628
}
1863218629
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
1863318630
send_val_by_ref:
18634-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
18631+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
1863518632
}
1863618633
value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
1863718634
ZVAL_COPY_VALUE(arg, value);
@@ -19455,7 +19452,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HA
1945519452
}
1945619453
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
1945719454
send_val_by_ref:
19458-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
19455+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
1945919456
}
1946019457
value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
1946119458
ZVAL_COPY_VALUE(arg, value);
@@ -19492,7 +19489,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_T
1949219489
}
1949319490
} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
1949419491
send_val_by_ref:
19495-
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
19492+
ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(arg_num, arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
1949619493
}
1949719494
value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
1949819495
ZVAL_COPY_VALUE(arg, value);

0 commit comments

Comments
 (0)