diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 331ef5105fa9d..c779f0351ea8a 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -1045,6 +1045,28 @@ static ZEND_METHOD(_ZendTestClass, takesUnionType) RETURN_NULL(); } +static ZEND_METHOD(_ZendTestClass, returnByRefIntProp) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_object *obj = Z_OBJ_P(ZEND_THIS); + zend_string *name = zend_string_init("intProp", strlen("intProp"), false); + zval *int_prop = obj->handlers->get_property_ptr_ptr(obj, name, BP_VAR_W, NULL); + zend_string_release_ex(name, false); + + ZEND_ASSERT(int_prop); + ZEND_ASSERT(!Z_ISERROR_P(int_prop)); + + if (!Z_ISREF_P(int_prop)) { + zend_property_info *prop_info = zend_get_property_info_for_slot(obj, int_prop); + ZEND_ASSERT(ZEND_TYPE_IS_SET(prop_info->type)); + ZVAL_MAKE_REF(int_prop); + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(int_prop), prop_info); + } + + ZVAL_COPY(return_value, int_prop); +} + // Returns a newly allocated DNF type `Iterator|(Traversable&Countable)`. // // We need to generate it "manually" because gen_stubs.php does not support codegen for DNF types ATM. diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 5c1bed2847822..d614868334e61 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -65,6 +65,8 @@ public function returnsThrowable(): Throwable {} static public function variadicTest(string|Iterator ...$elements) : static {} public function takesUnionType(stdclass|Iterator $arg): void {} + + public function &returnByRefIntProp(): int {} } class _ZendTestMagicCall diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 32229d9d9d323..4b37215d30bb4 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 53027610adee7e1c675b1c1b38886100ce4e63ef */ + * Stub hash: 9f38fdbb3b987bccaa873bd005559ce52b96b0dd */ ZEND_STATIC_ASSERT(PHP_VERSION_ID >= 80000, "test_arginfo.h only supports PHP version ID 80000 or newer, " "but it is included on an older PHP version"); @@ -187,6 +187,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class__ZendTestClass_takesUnionT ZEND_ARG_OBJ_TYPE_MASK(0, arg, stdclass|Iterator, 0, NULL) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class__ZendTestClass_returnByRefIntProp, 1, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class__ZendTestMagicCall___call, 0, 2, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, args, IS_ARRAY, 0) @@ -287,6 +290,7 @@ static ZEND_METHOD(_ZendTestClass, returnsStatic); static ZEND_METHOD(_ZendTestClass, returnsThrowable); static ZEND_METHOD(_ZendTestClass, variadicTest); static ZEND_METHOD(_ZendTestClass, takesUnionType); +static ZEND_METHOD(_ZendTestClass, returnByRefIntProp); static ZEND_METHOD(_ZendTestMagicCall, __call); static ZEND_METHOD(_ZendTestChildClass, returnsThrowable); static ZEND_METHOD(ZendAttributeTest, testMethod); @@ -426,6 +430,7 @@ static const zend_function_entry class__ZendTestClass_methods[] = { ZEND_ME(_ZendTestClass, returnsThrowable, arginfo_class__ZendTestClass_returnsThrowable, ZEND_ACC_PUBLIC) ZEND_ME(_ZendTestClass, variadicTest, arginfo_class__ZendTestClass_variadicTest, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(_ZendTestClass, takesUnionType, arginfo_class__ZendTestClass_takesUnionType, ZEND_ACC_PUBLIC) + ZEND_ME(_ZendTestClass, returnByRefIntProp, arginfo_class__ZendTestClass_returnByRefIntProp, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/ext/zend_test/tests/gen_stub_test_return_by_ref.phpt b/ext/zend_test/tests/gen_stub_test_return_by_ref.phpt new file mode 100644 index 0000000000000..a035ac390f373 --- /dev/null +++ b/ext/zend_test/tests/gen_stub_test_return_by_ref.phpt @@ -0,0 +1,51 @@ +--TEST-- +gen_stub.php: Test that return by ref flag is set +--EXTENSIONS-- +zend_test +--FILE-- +returnsReference()); + +$o = new _ZendTestClass(); +var_dump($o); +$i =& $o->returnByRefIntProp(); +var_dump($i); +$i = 24; +var_dump($i); +var_dump($o); + +?> +--EXPECT-- +bool(true) +object(_ZendTestClass)#2 (3) { + ["intProp"]=> + int(123) + ["classProp"]=> + NULL + ["classUnionProp"]=> + NULL + ["classIntersectionProp"]=> + uninitialized(Traversable&Countable) + ["readonlyProp"]=> + uninitialized(int) + ["dnfProperty"]=> + uninitialized(Iterator|(Traversable&Countable)) +} +int(123) +int(24) +object(_ZendTestClass)#2 (3) { + ["intProp"]=> + &int(24) + ["classProp"]=> + NULL + ["classUnionProp"]=> + NULL + ["classIntersectionProp"]=> + uninitialized(Traversable&Countable) + ["readonlyProp"]=> + uninitialized(int) + ["dnfProperty"]=> + uninitialized(Iterator|(Traversable&Countable)) +}