Skip to content

Commit 34d9a71

Browse files
committed
Fix lineno in backtrace of multi-line function calls
Closes GH-8810
1 parent 827754a commit 34d9a71

File tree

4 files changed

+42
-20
lines changed

4 files changed

+42
-20
lines changed

Zend/tests/gh8810.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
GH-8810: Fix reported line number of multi-line function call
3+
--FILE--
4+
<?php
5+
6+
function foo($bar, $baz) {
7+
throw new Exception();
8+
}
9+
10+
foo(
11+
'bar',
12+
'baz',
13+
);
14+
15+
?>
16+
--EXPECTF--
17+
Fatal error: Uncaught Exception in %s:4
18+
Stack trace:
19+
#0 %s(7): foo('bar', 'baz')
20+
#1 {main}
21+
thrown in %s on line 4

Zend/zend_compile.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3623,7 +3623,7 @@ ZEND_API zend_uchar zend_get_call_op(const zend_op *init_op, zend_function *fbc)
36233623
}
36243624
/* }}} */
36253625

3626-
static bool zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc) /* {{{ */
3626+
static bool zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc, uint32_t lineno) /* {{{ */
36273627
{
36283628
zend_op *opline;
36293629
uint32_t opnum_init = get_next_op_number() - 1;
@@ -3660,6 +3660,7 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, zend_fun
36603660
if (may_have_extra_named_args) {
36613661
opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS;
36623662
}
3663+
opline->lineno = lineno;
36633664
zend_do_extended_fcall_end();
36643665
return false;
36653666
}
@@ -3678,7 +3679,7 @@ static bool zend_compile_function_name(znode *name_node, zend_ast *name_ast) /*
36783679
}
36793680
/* }}} */
36803681

3681-
static void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
3682+
static void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast, uint32_t lineno) /* {{{ */
36823683
{
36833684
zend_op *opline = get_next_op();
36843685
opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
@@ -3687,11 +3688,11 @@ static void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args
36873688
Z_STR(name_node->u.constant));
36883689
opline->result.num = zend_alloc_cache_slot();
36893690

3690-
zend_compile_call_common(result, args_ast, NULL);
3691+
zend_compile_call_common(result, args_ast, NULL, lineno);
36913692
}
36923693
/* }}} */
36933694

3694-
static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
3695+
static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast, uint32_t lineno) /* {{{ */
36953696
{
36963697
if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
36973698
const char *colon;
@@ -3721,7 +3722,7 @@ static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast
37213722
zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, name_node);
37223723
}
37233724

3724-
zend_compile_call_common(result, args_ast, NULL);
3725+
zend_compile_call_common(result, args_ast, NULL, lineno);
37253726
}
37263727
/* }}} */
37273728

@@ -4015,7 +4016,7 @@ static zend_result zend_compile_func_cuf(znode *result, zend_ast_list *args, zen
40154016
}
40164017
/* }}} */
40174018

4018-
static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc) /* {{{ */
4019+
static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc, uint32_t lineno) /* {{{ */
40194020
{
40204021
if (EG(assertions) >= 0) {
40214022
znode name_node;
@@ -4050,7 +4051,7 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string
40504051
zend_ast_list_add((zend_ast *) args, arg);
40514052
}
40524053

4053-
zend_compile_call_common(result, (zend_ast*)args, fbc);
4054+
zend_compile_call_common(result, (zend_ast*)args, fbc, lineno);
40544055

40554056
opline = &CG(active_op_array)->opcodes[check_op_number];
40564057
opline->op2.opline_num = get_next_op_number();
@@ -4377,7 +4378,7 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
43774378

43784379
if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
43794380
zend_compile_expr(&name_node, name_ast);
4380-
zend_compile_dynamic_call(result, &name_node, args_ast);
4381+
zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno);
43814382
return;
43824383
}
43834384

@@ -4386,9 +4387,9 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
43864387
if (runtime_resolution) {
43874388
if (zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "assert")
43884389
&& !is_callable_convert) {
4389-
zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL);
4390+
zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL, ast->lineno);
43904391
} else {
4391-
zend_compile_ns_call(result, &name_node, args_ast);
4392+
zend_compile_ns_call(result, &name_node, args_ast, ast->lineno);
43924393
}
43934394
return;
43944395
}
@@ -4405,7 +4406,7 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
44054406

44064407
/* Special assert() handling should apply independently of compiler flags. */
44074408
if (fbc && zend_string_equals_literal(lcname, "assert") && !is_callable_convert) {
4408-
zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc);
4409+
zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc, ast->lineno);
44094410
zend_string_release(lcname);
44104411
zval_ptr_dtor(&name_node.u.constant);
44114412
return;
@@ -4417,7 +4418,7 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
44174418
|| (fbc->type == ZEND_USER_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_OTHER_FILES) && fbc->op_array.filename != CG(active_op_array)->filename)
44184419
) {
44194420
zend_string_release_ex(lcname, 0);
4420-
zend_compile_dynamic_call(result, &name_node, args_ast);
4421+
zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno);
44214422
return;
44224423
}
44234424

@@ -4436,7 +4437,7 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
44364437
opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
44374438
opline->result.num = zend_alloc_cache_slot();
44384439

4439-
zend_compile_call_common(result, args_ast, fbc);
4440+
zend_compile_call_common(result, args_ast, fbc, ast->lineno);
44404441
}
44414442
}
44424443
/* }}} */
@@ -4500,7 +4501,7 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type
45004501
}
45014502
}
45024503

4503-
if (zend_compile_call_common(result, args_ast, fbc)) {
4504+
if (zend_compile_call_common(result, args_ast, fbc, ast->lineno)) {
45044505
if (short_circuiting_checkpoint != zend_short_circuiting_checkpoint()) {
45054506
zend_error_noreturn(E_COMPILE_ERROR,
45064507
"Cannot combine nullsafe operator with Closure creation");
@@ -4597,7 +4598,7 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type
45974598
}
45984599
}
45994600

4600-
zend_compile_call_common(result, args_ast, fbc);
4601+
zend_compile_call_common(result, args_ast, fbc, ast->lineno);
46014602
}
46024603
/* }}} */
46034604

@@ -4629,7 +4630,7 @@ static void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
46294630
SET_NODE(opline->op1, &class_node);
46304631
}
46314632

4632-
zend_compile_call_common(&ctor_result, args_ast, NULL);
4633+
zend_compile_call_common(&ctor_result, args_ast, NULL, ast->lineno);
46334634
zend_do_free(&ctor_result);
46344635
}
46354636
/* }}} */

sapi/phpdbg/tests/exceptions_001.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ prompt> handle first
1414
00017: } catch (\Exception $e) {
1515
00018: var_dump($e);
1616
prompt> frame #0: {closure}() at %s:16
17-
frame #1: {main} at %s:22
17+
frame #1: {main} at %s:14
1818
prompt> 3
1919
prompt> [Uncaught Error in %s on line 16]
2020
Error: Call to undefined function foo() in %s:16
2121
Stack trace:
22-
#0 %s(22): {closure}()
22+
#0 %s(14): {closure}()
2323
#1 {main}
2424
[Script ended normally]
2525
prompt>

sapi/phpdbg/tests/exceptions_002.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ prompt>
1717
Fatal error: Uncaught Error: Call to undefined function next_error() in eval()'d code:1
1818
Stack trace:
1919
#0 %s(16): unknown()
20-
#1 %s(20): {closure}()
20+
#1 %s(14): {closure}()
2121
#2 {main}
2222
thrown in eval()'d code on line 1
2323
prompt> [Uncaught Error in %s on line 16]
2424
Error: Call to undefined function foo() in %s:16
2525
Stack trace:
26-
#0 %s(20): {closure}()
26+
#0 %s(14): {closure}()
2727
#1 {main}
2828
[Script ended normally]
2929
prompt> [The stack contains nothing !]

0 commit comments

Comments
 (0)