diff --git a/Zend/tests/gh16515.phpt b/Zend/tests/gh16515.phpt new file mode 100644 index 0000000000000..63bb447e7ba2e --- /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 bbd3b85e6fba0..f261edb22bc90 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -845,7 +845,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; + trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC|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 def9695ed98bd..3446fb2c96434 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1281,7 +1281,10 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend 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; }