Skip to content
Open
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
5 changes: 4 additions & 1 deletion Zend/Optimizer/zend_optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,10 @@ static void zend_optimize(zend_op_array *op_array,
}

if (ctx->debug_level & ZEND_DUMP_BEFORE_OPTIMIZER) {
zend_dump_op_array(op_array, ZEND_DUMP_LIVE_RANGES, "before optimizer", NULL);
uint32_t additional_dump_flags = (ctx->debug_level & ZEND_DUMP_LINE_NUMBERS_PASSTHRU)
? ZEND_DUMP_LINE_NUMBERS
: 0;
zend_dump_op_array(op_array, ZEND_DUMP_LIVE_RANGES|additional_dump_flags, "before optimizer", NULL);
}

/* pass 1 (Simple local optimizations)
Expand Down
1 change: 1 addition & 0 deletions Zend/Optimizer/zend_optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#define ZEND_DUMP_DFA_SSA (1<<27)
#define ZEND_DUMP_DFA_SSA_VARS (1<<28)
#define ZEND_DUMP_SCCP (1<<29)
#define ZEND_DUMP_LINE_NUMBERS_PASSTHRU (1<<30)

typedef struct _zend_script {
zend_string *filename;
Expand Down
44 changes: 33 additions & 11 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -7125,6 +7125,8 @@ static void zend_compile_match(znode *result, zend_ast *ast)
zend_ast *arm_ast = arms->child[i];
zend_ast *body_ast = arm_ast->child[1];

CG(zend_lineno) = zend_ast_get_lineno(arm_ast);

if (arm_ast->child[0] != NULL) {
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);

Expand Down Expand Up @@ -10728,6 +10730,8 @@ static void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&left_node, left_ast);
zend_compile_expr(&right_node, right_ast);

CG(zend_lineno) = ast->lineno;

if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
if (zend_try_ct_eval_binary_op(&result->u.constant, opcode,
&left_node.u.constant, &right_node.u.constant)
Expand Down Expand Up @@ -12327,9 +12331,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */

static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
{
/* CG(zend_lineno) = ast->lineno; */
CG(zend_lineno) = zend_ast_get_lineno(ast);

if (CG(memoize_mode) != ZEND_MEMOIZE_NONE) {
zend_compile_memoized_expr(result, ast, BP_VAR_R);
return;
Expand Down Expand Up @@ -12468,6 +12469,9 @@ static void zend_compile_expr(znode *result, zend_ast *ast)
{
zend_check_stack_limit();

uint32_t prev_lineno = CG(zend_lineno);
CG(zend_lineno) = zend_ast_get_lineno(ast);

uint32_t checkpoint = zend_short_circuiting_checkpoint();
zend_compile_expr_inner(result, ast);
zend_short_circuiting_commit(checkpoint, result, ast);
Expand All @@ -12477,12 +12481,12 @@ static void zend_compile_expr(znode *result, zend_ast *ast)
ZEND_ASSERT(result->op_type != IS_VAR);
}
#endif

CG(zend_lineno) = prev_lineno;
}

static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t type, bool by_ref)
{
CG(zend_lineno) = zend_ast_get_lineno(ast);

if (CG(memoize_mode) != ZEND_MEMOIZE_NONE) {
switch (ast->kind) {
case ZEND_AST_CALL:
Expand Down Expand Up @@ -12543,6 +12547,9 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo
{
zend_check_stack_limit();

uint32_t prev_lineno = CG(zend_lineno);
CG(zend_lineno) = zend_ast_get_lineno(ast);

uint32_t checkpoint = zend_short_circuiting_checkpoint();
zend_op *opcode = zend_compile_var_inner(result, ast, type, by_ref);
zend_short_circuiting_commit(checkpoint, result, ast);
Expand All @@ -12556,32 +12563,47 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo
ZEND_ASSERT(result->op_type != IS_VAR);
}
#endif

CG(zend_lineno) = prev_lineno;

return opcode;
}

static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type, bool by_ref) /* {{{ */
{
zend_check_stack_limit();

uint32_t prev_lineno = CG(zend_lineno);
CG(zend_lineno) = zend_ast_get_lineno(ast);

zend_op *opline;
switch (ast->kind) {
case ZEND_AST_VAR:
return zend_compile_simple_var(result, ast, type, true);
opline = zend_compile_simple_var(result, ast, type, true);
break;
case ZEND_AST_DIM:
return zend_delayed_compile_dim(result, ast, type, by_ref);
opline = zend_delayed_compile_dim(result, ast, type, by_ref);
break;
case ZEND_AST_PROP:
case ZEND_AST_NULLSAFE_PROP:
{
zend_op *opline = zend_delayed_compile_prop(result, ast, type);
opline = zend_delayed_compile_prop(result, ast, type);
if (by_ref) {
opline->extended_value |= ZEND_FETCH_REF;
}
return opline;
break;
}
case ZEND_AST_STATIC_PROP:
return zend_compile_static_prop(result, ast, type, by_ref, true);
opline = zend_compile_static_prop(result, ast, type, by_ref, true);
break;
default:
return zend_compile_var(result, ast, type, false);
opline = zend_compile_var(result, ast, type, false);
break;
}

CG(zend_lineno) = prev_lineno;

return opline;
}
/* }}} */

Expand Down
35 changes: 35 additions & 0 deletions ext/opcache/tests/gh18985.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
GH-18985: Wrong lineno for multiline expressions
--EXTENSIONS--
opcache
--INI--
opcache.enable_cli=1
opcache.opt_debug_level=0x40010000
--FILE--
<?php

echo match(15) {
13 => "A",
15 => "B",
default => "C",
};

?>
--EXPECTF--
$_main:
; (lines=9, args=0, vars=0, tmps=%s)
; (before optimizer)
; %sgh18985.php:1-10
; return [] RANGE[0..0]
L0003 0000 MATCH int(15) 13: 0001, 15: 0003, default: 0005
L0004 0001 T1 = QM_ASSIGN string("A")
L0004 0002 JMP 0007
L0005 0003 T1 = QM_ASSIGN string("B")
L0005 0004 JMP 0007
L0006 0005 T1 = QM_ASSIGN string("C")
L0006 0006 JMP 0007
L0003 0007 ECHO T1
L0010 0008 RETURN int(1)
LIVE RANGES:
1: 0006 - 0007 (tmp/var)
B
4 changes: 2 additions & 2 deletions ext/opcache/tests/jit/shift_right_004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ Warning: Undefined array key 0 in %sshift_right_004.php on line 7

Deprecated: Implicit conversion from float %f to int loses precision in %sshift_right_004.php on line 8

Warning: A non-numeric value encountered in %sshift_right_004.php on line 7
Warning: A non-numeric value encountered in %sshift_right_004.php on line 6

Warning: A non-numeric value encountered in %sshift_right_004.php on line 7
Warning: A non-numeric value encountered in %sshift_right_004.php on line 6

Fatal error: Uncaught ArithmeticError: Bit shift by negative number in %sshift_right_004.php:8
Stack trace:
Expand Down
4 changes: 2 additions & 2 deletions ext/opcache/tests/jit/switch_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ foo();
?>
DONE
--EXPECTF--
Warning: Undefined variable $y in %sswitch_001.php on line 4
Warning: Undefined variable $y in %sswitch_001.php on line 3

Warning: Undefined variable $y in %sswitch_001.php on line 5
Warning: Undefined variable $y in %sswitch_001.php on line 3
DONE
Loading