Skip to content

Commit f4e06ea

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Create reference wrappers in SEND_UNPACK if necessary
2 parents 6858ad1 + 02244d5 commit f4e06ea

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Unpack iterator by reference with type check
3+
--FILE--
4+
<?php
5+
function test(T &$a) {
6+
}
7+
function gen() {
8+
yield null;
9+
}
10+
try {
11+
test(...gen());
12+
} catch (TypeError $e) {
13+
echo $e->getMessage(), "\n";
14+
}
15+
?>
16+
--EXPECTF--
17+
Warning: Cannot pass by-reference argument 1 of test() by unpacking a Traversable, passing by-value instead in %s on line %d
18+
test(): Argument #1 ($a) must be of type T, null given, called in %s on line %d

Zend/zend_vm_def.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5154,6 +5154,9 @@ ZEND_VM_C_LABEL(send_again):
51545154
break;
51555155
}
51565156

5157+
ZVAL_DEREF(arg);
5158+
Z_TRY_ADDREF_P(arg);
5159+
51575160
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
51585161
zend_error(
51595162
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
@@ -5162,9 +5165,11 @@ ZEND_VM_C_LABEL(send_again):
51625165
EX(call)->func->common.scope ? "::" : "",
51635166
ZSTR_VAL(EX(call)->func->common.function_name)
51645167
);
5168+
ZVAL_NEW_REF(top, arg);
5169+
} else {
5170+
ZVAL_COPY_VALUE(top, arg);
51655171
}
51665172

5167-
ZVAL_COPY_DEREF(top, arg);
51685173
zend_string_release(name);
51695174
} else {
51705175
if (have_named_params) {
@@ -5173,6 +5178,11 @@ ZEND_VM_C_LABEL(send_again):
51735178
break;
51745179
}
51755180

5181+
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
5182+
top = ZEND_CALL_ARG(EX(call), arg_num);
5183+
ZVAL_DEREF(arg);
5184+
Z_TRY_ADDREF_P(arg);
5185+
51765186
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
51775187
zend_error(
51785188
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
@@ -5181,12 +5191,11 @@ ZEND_VM_C_LABEL(send_again):
51815191
EX(call)->func->common.scope ? "::" : "",
51825192
ZSTR_VAL(EX(call)->func->common.function_name)
51835193
);
5194+
ZVAL_NEW_REF(top, arg);
5195+
} else {
5196+
ZVAL_COPY_VALUE(top, arg);
51845197
}
51855198

5186-
5187-
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
5188-
top = ZEND_CALL_ARG(EX(call), arg_num);
5189-
ZVAL_COPY_DEREF(top, arg);
51905199
ZEND_CALL_NUM_ARGS(EX(call))++;
51915200
}
51925201

Zend/zend_vm_execute.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,6 +2258,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
22582258
break;
22592259
}
22602260

2261+
ZVAL_DEREF(arg);
2262+
Z_TRY_ADDREF_P(arg);
2263+
22612264
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
22622265
zend_error(
22632266
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
@@ -2266,9 +2269,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
22662269
EX(call)->func->common.scope ? "::" : "",
22672270
ZSTR_VAL(EX(call)->func->common.function_name)
22682271
);
2272+
ZVAL_NEW_REF(top, arg);
2273+
} else {
2274+
ZVAL_COPY_VALUE(top, arg);
22692275
}
22702276

2271-
ZVAL_COPY_DEREF(top, arg);
22722277
zend_string_release(name);
22732278
} else {
22742279
if (have_named_params) {
@@ -2277,6 +2282,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
22772282
break;
22782283
}
22792284

2285+
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
2286+
top = ZEND_CALL_ARG(EX(call), arg_num);
2287+
ZVAL_DEREF(arg);
2288+
Z_TRY_ADDREF_P(arg);
2289+
22802290
if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
22812291
zend_error(
22822292
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
@@ -2285,12 +2295,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
22852295
EX(call)->func->common.scope ? "::" : "",
22862296
ZSTR_VAL(EX(call)->func->common.function_name)
22872297
);
2298+
ZVAL_NEW_REF(top, arg);
2299+
} else {
2300+
ZVAL_COPY_VALUE(top, arg);
22882301
}
22892302

2290-
2291-
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
2292-
top = ZEND_CALL_ARG(EX(call), arg_num);
2293-
ZVAL_COPY_DEREF(top, arg);
22942303
ZEND_CALL_NUM_ARGS(EX(call))++;
22952304
}
22962305

0 commit comments

Comments
 (0)