diff --git a/Zend/tests/gh16515.phpt b/Zend/tests/gh16515.phpt new file mode 100644 index 00000000000..63bb447e7ba --- /dev/null +++ b/Zend/tests/gh16515.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-16515: Incorrect propagation of ZEND_ACC_RETURN_REFERENCE for call trampoline +--FILE-- +bar(...)); + +?> +--EXPECTF-- +Notice: Only variable references should be returned by reference in %s on line %d diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 997733b6a5e..629aa7d51a8 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -871,7 +871,7 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* { memset(&trampoline, 0, sizeof(zend_internal_function)); trampoline.type = ZEND_INTERNAL_FUNCTION; - trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC); + trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE); trampoline.handler = zend_closure_call_magic; trampoline.function_name = mptr->common.function_name; trampoline.scope = mptr->common.scope; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 6f5cc8b4521..17b85dbfe2e 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1614,7 +1614,10 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce func->arg_flags[0] = 0; func->arg_flags[1] = 0; func->arg_flags[2] = 0; - func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_PUBLIC | ZEND_ACC_VARIADIC; + func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE + | ZEND_ACC_PUBLIC + | ZEND_ACC_VARIADIC + | (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE); if (is_static) { func->fn_flags |= ZEND_ACC_STATIC; }