Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Zend/tests/magic_methods/constructor_destructor_return.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Returning values from constructors and destructors is deprecated
--FILE--
<?php

class A {
public function __construct() { return ''; }
public function __destruct() { return ''; }
}

class Gen {
public function __construct() { yield ''; }
public function __destruct() { yield ''; }
}

?>
--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
1 change: 1 addition & 0 deletions Zend/tests/prop_const_expr/non_enums_catchable.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions Zend/tests/traits/bug60536_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
30 changes: 24 additions & 6 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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);
}
Expand Down
5 changes: 4 additions & 1 deletion ext/reflection/tests/bug36434.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 11 additions & 4 deletions ext/zend_test/tests/zend_object_init_with_constructor.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Loading