diff --git a/Zend/tests/magic_methods/constructor_destructor_return.phpt b/Zend/tests/magic_methods/constructor_destructor_return.phpt new file mode 100644 index 000000000000..5befa60760b9 --- /dev/null +++ b/Zend/tests/magic_methods/constructor_destructor_return.phpt @@ -0,0 +1,24 @@ +--TEST-- +Returning values from constructors and destructors is deprecated +--FILE-- + +--EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a destructor is deprecated in %s on line %d + +Deprecated: Making a constructor a Generator is deprecated in %s on line %d + +Deprecated: Making a destructor a Generator is deprecated in %s on line %d diff --git a/Zend/tests/prop_const_expr/non_enums_catchable.phpt b/Zend/tests/prop_const_expr/non_enums_catchable.phpt index 6f410ac7acbe..702bc024122d 100644 --- a/Zend/tests/prop_const_expr/non_enums_catchable.phpt +++ b/Zend/tests/prop_const_expr/non_enums_catchable.phpt @@ -18,6 +18,7 @@ const A_prop = (new A)->{new Printer ? 'printer' : null}; ?> --EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d Printer Fatal error: Uncaught Error: Fetching properties on non-enums in constant expressions is not allowed in %s:%d diff --git a/Zend/tests/traits/bug60536_001.phpt b/Zend/tests/traits/bug60536_001.phpt index a58098ca3112..712600a4b1d1 100644 --- a/Zend/tests/traits/bug60536_001.phpt +++ b/Zend/tests/traits/bug60536_001.phpt @@ -23,5 +23,9 @@ $a->__construct(); echo "DONE"; ?> --EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + Warning: Undefined property: Z::$x in %s on line %d DONE diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 105f99d24171..a1e488ba5e7f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -530,6 +530,12 @@ ZEND_API bool zend_is_compiling(void) /* {{{ */ } /* }}} */ +static bool zend_is_constructor(const zend_string *name) /* {{{ */ +{ + return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME); +} +/* }}} */ + static zend_always_inline uint32_t get_temporary_variable(void) /* {{{ */ { return (uint32_t)CG(active_op_array)->T++; @@ -5549,12 +5555,6 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type } /* }}} */ -static bool zend_is_constructor(const zend_string *name) /* {{{ */ -{ - return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME); -} -/* }}} */ - static bool is_func_accessible(const zend_function *fbc) { if ((fbc->common.fn_flags & ZEND_ACC_PUBLIC) || fbc->common.scope == CG(active_class_entry)) { @@ -5993,6 +5993,16 @@ static void zend_compile_return(const zend_ast *ast) /* {{{ */ zend_compile_expr(&expr_node, expr_ast); } + if (expr_ast) { + if (CG(active_class_entry) != NULL) { + if (zend_is_constructor(CG(active_op_array)->function_name)) { + zend_error(E_DEPRECATED, "Returning a value from a constructor is deprecated"); + } else if (zend_string_equals_literal_ci(CG(active_op_array)->function_name, ZEND_DESTRUCTOR_FUNC_NAME)) { + zend_error(E_DEPRECATED, "Returning a value from a destructor is deprecated"); + } + } + } + if ((CG(active_op_array)->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) && (expr_node.op_type == IS_CV || (by_ref && expr_node.op_type == IS_VAR)) && zend_has_finally()) { @@ -8843,6 +8853,14 @@ static zend_op_array *zend_compile_func_decl_ex( zend_compile_params(params_ast, return_type_ast, is_method && zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME) ? IS_STRING : 0); if (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { + if (CG(active_class_entry) != NULL) { + if (zend_is_constructor(CG(active_op_array)->function_name)) { + zend_error(E_DEPRECATED, "Making a constructor a Generator is deprecated"); + } else if (zend_string_equals_literal_ci(CG(active_op_array)->function_name, ZEND_DESTRUCTOR_FUNC_NAME)) { + zend_error(E_DEPRECATED, "Making a destructor a Generator is deprecated"); + } + } + zend_mark_function_as_generator(); zend_emit_op(NULL, ZEND_GENERATOR_CREATE, NULL, NULL); } diff --git a/ext/reflection/tests/bug36434.phpt b/ext/reflection/tests/bug36434.phpt index 3f4cc70c7554..0dfa5d117b2c 100644 --- a/ext/reflection/tests/bug36434.phpt +++ b/ext/reflection/tests/bug36434.phpt @@ -26,6 +26,9 @@ foreach ($r->GetProperties() as $p) } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d bar foo ancestor ancestor diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt index 4a82d5893157..dcfa8f2e759c 100644 --- a/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt @@ -25,5 +25,6 @@ try { echo "Exception caught: " . $e->getMessage() . "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning a value from a destructor is deprecated in %s on line %d Exception caught: Array was modified during array_splice operation diff --git a/ext/zend_test/tests/zend_object_init_with_constructor.phpt b/ext/zend_test/tests/zend_object_init_with_constructor.phpt index 65b111447f0b..aa3ad7ee845a 100644 --- a/ext/zend_test/tests/zend_object_init_with_constructor.phpt +++ b/ext/zend_test/tests/zend_object_init_with_constructor.phpt @@ -139,7 +139,14 @@ $o = zend_object_init_with_constructor("TestUserWithConstructorNoParams"); var_dump($o); unset($o); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d + +Deprecated: Returning a value from a constructor is deprecated in %s on line %d Testing impossible initializations Error: Cannot instantiate interface _ZendTestInterface Error: Cannot instantiate trait _ZendTestTrait @@ -152,14 +159,14 @@ Testing param passing ArgumentCountError: Too few arguments to function TestUserWithConstructorArgs::__construct(), 0 passed and exactly 2 expected TypeError: TestUserWithConstructorArgs::__construct(): Argument #1 ($int_param) must be of type int, string given Error: Unknown named parameter $unused_param -object(TestUserWithConstructorArgs)#1 (0) { +object(TestUserWithConstructorArgs)#%d (0) { } Destructor for TestUserWithConstructorArgs Passing too many args to constructor -object(TestUserWithConstructorArgs)#1 (0) { +object(TestUserWithConstructorArgs)#%d (0) { } Destructor for TestUserWithConstructorArgs Testing class with defined constructor and no params -object(TestUserWithConstructorNoParams)#1 (0) { +object(TestUserWithConstructorNoParams)#%d (0) { } Destructor for TestUserWithConstructorNoParams