From 5c69644f7c864a317f6cb8db6ce8a4dde2cd9de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sun, 7 Jun 2020 12:45:15 +0200 Subject: [PATCH 1/3] Fix #79679: Constructor can not return any value (always void) --- tests/classes/bug79679.phpt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/classes/bug79679.phpt diff --git a/tests/classes/bug79679.phpt b/tests/classes/bug79679.phpt new file mode 100644 index 0000000000000..855ec6457a970 --- /dev/null +++ b/tests/classes/bug79679.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #79679: Constructor can not return any value (always void). +--FILE-- + +--EXPECTF-- +Fatal error: A void function must not return a value in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d From 24f8f0579064724d76ed1608f8248394e99c94d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 15 Jun 2020 10:50:42 +0200 Subject: [PATCH 2/3] impl --- Zend/zend_compile.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 86e169893ab3b..26169c53e4770 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6464,8 +6464,16 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /* zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var); } - zend_compile_params(params_ast, return_type_ast, - is_method && zend_string_equals_literal_ci(decl->name, "__toString") ? IS_STRING : 0); + uint32_t fallback_return_type = 0; + if (is_method) { + if (zend_string_equals_literal_ci(decl->name, "__toString")) { + fallback_return_type = IS_STRING; + } else if (zend_string_equals_literal_ci(decl->name, "__construct")) { + fallback_return_type = IS_VOID; + } + } + zend_compile_params(params_ast, return_type_ast, fallback_return_type); + if (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { zend_mark_function_as_generator(); zend_emit_op(NULL, ZEND_GENERATOR_CREATE, NULL, NULL); From 1405a5f43c9834b38f7c82f65e380470330cb073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 15 Jun 2020 11:28:22 +0200 Subject: [PATCH 3/3] allow constructor/destructor void return type --- Zend/zend_compile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 26169c53e4770..0374921a01559 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6902,7 +6902,8 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) / zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name)); } - if (ce->constructor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + if (ce->constructor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE + && ZEND_TYPE_PURE_MASK(ce->constructor->common.arg_info[-1].type) != MAY_BE_VOID) { zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot declare a return type", ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name)); @@ -6912,7 +6913,8 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) / if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) { zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ZSTR_VAL(ce->name), ZSTR_VAL(ce->destructor->common.function_name)); - } else if (ce->destructor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + } else if (ce->destructor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE + && ZEND_TYPE_PURE_MASK(ce->destructor->common.arg_info[-1].type) != MAY_BE_VOID) { zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot declare a return type", ZSTR_VAL(ce->name), ZSTR_VAL(ce->destructor->common.function_name));