diff --git a/NEWS b/NEWS index 86b6bd3e2e0c..5e9f92701439 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug GH-15375 (Nested "yield from" skips items after a valid() or next() call on the inner generator). (iliaal) + . Fixed bug GH-22727 (RETURN opcodes for multiline expressions use the wrong + line). (Joost Waaijer) . Fixed bug GH-23301 (Nested "yield from" yields a value twice when the middle generator delegates again). (Lazizbek Ergashev) diff --git a/Zend/tests/gh22727.phpt b/Zend/tests/gh22727.phpt new file mode 100644 index 000000000000..a65ea727dee9 --- /dev/null +++ b/Zend/tests/gh22727.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-22727: Return opcodes use the return statement line for multiline expressions +--FILE-- + 'not an int', + }; +} + +try { + test(); +} catch (Throwable $e) { + echo $e::class, ': on line ', $e->getLine(), "\n"; +} + +?> +--EXPECT-- +TypeError: on line 5 diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 42c136d6bf36..0e493f098eca 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5687,6 +5687,7 @@ static bool zend_has_finally(void) /* {{{ */ static void zend_compile_return(zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; + uint32_t return_lineno = CG(zend_lineno); bool is_generator = (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0; bool by_ref = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; @@ -5708,6 +5709,8 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */ zend_compile_expr(&expr_node, expr_ast); } + CG(zend_lineno) = return_lineno; + 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()) {