Skip to content

Commit fe90756

Browse files
committed
Forbid "return;" for typed returns already at compile-time
These would otherwise generate a "none returned" error at runtime. Catch them early.
1 parent cb3825a commit fe90756

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

Zend/tests/return_types/029.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function foo() : array {
99
try {
1010
throw new Exception("xxxx");
1111
} finally {
12-
return ;
12+
return null;
1313
}
1414
}
1515

@@ -21,7 +21,7 @@ Stack trace:
2121
#0 %s(%d): foo()
2222
#1 {main}
2323

24-
Next TypeError: Return value of foo() must be of the type array, none returned in %s29.php:%d
24+
Next TypeError: Return value of foo() must be of the type array, null returned in %s29.php:%d
2525
Stack trace:
2626
#0 %s(%d): foo()
2727
#1 {main}

Zend/tests/return_types/bug71092.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ function boom(): array {
99
$data = [['id']];
1010
switch ($data[0]) {
1111
case ['id']:
12-
return;
12+
return null;
1313
}
1414
}
1515

1616
boom();
1717
?>
1818
--EXPECTF--
19-
Fatal error: Uncaught TypeError: Return value of boom() must be of the type array, none returned in %sbug71092.php:%d
19+
Fatal error: Uncaught TypeError: Return value of boom() must be of the type array, null returned in %sbug71092.php:%d
2020
Stack trace:
2121
#0 %s(%d): boom()
2222
#1 {main}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Typed return without value generates compile-time error
3+
--FILE--
4+
<?php
5+
6+
function test() : int {
7+
return;
8+
}
9+
10+
test();
11+
12+
?>
13+
--EXPECTF--
14+
Fatal error: A function with return type must return a value in %s on line %d

Zend/zend_compile.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,7 +2264,8 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */
22642264
}
22652265
/* }}} */
22662266

2267-
static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info) /* {{{ */
2267+
static void zend_emit_return_type_check(
2268+
znode *expr, zend_arg_info *return_info, zend_bool implicit) /* {{{ */
22682269
{
22692270
/* `return ...;` is illegal in a void function (but `return;` isn't) */
22702271
if (return_info->type_hint == IS_VOID) {
@@ -2278,6 +2279,11 @@ static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info)
22782279
if (return_info->type_hint != IS_UNDEF) {
22792280
zend_op *opline;
22802281

2282+
if (!expr && !implicit) {
2283+
zend_error_noreturn(E_COMPILE_ERROR,
2284+
"A function with return type must return a value");
2285+
}
2286+
22812287
if (expr && expr->op_type == IS_CONST) {
22822288
if ((return_info->type_hint == Z_TYPE(expr->u.constant))
22832289
||((return_info->type_hint == _IS_BOOL)
@@ -2312,7 +2318,7 @@ void zend_emit_final_return(int return_one) /* {{{ */
23122318
zend_bool returns_reference = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
23132319

23142320
if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
2315-
zend_emit_return_type_check(NULL, CG(active_op_array)->arg_info - 1);
2321+
zend_emit_return_type_check(NULL, CG(active_op_array)->arg_info - 1, 1);
23162322
}
23172323

23182324
zn.op_type = IS_CONST;
@@ -4058,7 +4064,8 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
40584064

40594065
/* Generator return types are handled separately */
40604066
if (!(CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) && CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
4061-
zend_emit_return_type_check(expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1);
4067+
zend_emit_return_type_check(
4068+
expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0);
40624069
}
40634070

40644071
zend_handle_loops_and_finally();

0 commit comments

Comments
 (0)