mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix ZEND_MATCH_ERROR misoptimization
op1 of ZEND_MATCH_ERROR, which refers to the match expression, is not freed by MATCH_ERROR itself. Instead, it is freed by ZEND_HANDLE_EXCEPTION. For normal control flow, a FREE is placed at the end of the match expression. Since FREE may appear after MATCH_ERROR in the opcode sequence, we need to correctly handle op1 of MATCH_ERROR as alive. Fixes GH-17106 Closes GH-17108
This commit is contained in:
3
NEWS
3
NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|
|||||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
?? ??? ????, PHP 8.3.16
|
?? ??? ????, PHP 8.3.16
|
||||||
|
|
||||||
|
- Core:
|
||||||
|
. Fixed bug GH-17106 (ZEND_MATCH_ERROR misoptimization). (ilutov)
|
||||||
|
|
||||||
- DBA:
|
- DBA:
|
||||||
. Skip test if inifile is disabled. (orlitzky)
|
. Skip test if inifile is disabled. (orlitzky)
|
||||||
|
|
||||||
|
|||||||
@@ -640,6 +640,7 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array,
|
|||||||
case ZEND_SWITCH_LONG:
|
case ZEND_SWITCH_LONG:
|
||||||
case ZEND_SWITCH_STRING:
|
case ZEND_SWITCH_STRING:
|
||||||
case ZEND_MATCH:
|
case ZEND_MATCH:
|
||||||
|
case ZEND_MATCH_ERROR:
|
||||||
case ZEND_JMP_NULL: {
|
case ZEND_JMP_NULL: {
|
||||||
zend_op *end = op_array->opcodes + op_array->last;
|
zend_op *end = op_array->opcodes + op_array->last;
|
||||||
while (opline < end) {
|
while (opline < end) {
|
||||||
@@ -652,6 +653,7 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array,
|
|||||||
&& opline->opcode != ZEND_SWITCH_LONG
|
&& opline->opcode != ZEND_SWITCH_LONG
|
||||||
&& opline->opcode != ZEND_SWITCH_STRING
|
&& opline->opcode != ZEND_SWITCH_STRING
|
||||||
&& opline->opcode != ZEND_MATCH
|
&& opline->opcode != ZEND_MATCH
|
||||||
|
&& opline->opcode != ZEND_MATCH_ERROR
|
||||||
&& opline->opcode != ZEND_JMP_NULL
|
&& opline->opcode != ZEND_JMP_NULL
|
||||||
&& (opline->opcode != ZEND_FREE
|
&& (opline->opcode != ZEND_FREE
|
||||||
|| opline->extended_value != ZEND_FREE_ON_RETURN);
|
|| opline->extended_value != ZEND_FREE_ON_RETURN);
|
||||||
|
|||||||
@@ -877,6 +877,7 @@ static bool keeps_op1_alive(zend_op *opline) {
|
|||||||
|| opline->opcode == ZEND_SWITCH_LONG
|
|| opline->opcode == ZEND_SWITCH_LONG
|
||||||
|| opline->opcode == ZEND_SWITCH_STRING
|
|| opline->opcode == ZEND_SWITCH_STRING
|
||||||
|| opline->opcode == ZEND_MATCH
|
|| opline->opcode == ZEND_MATCH
|
||||||
|
|| opline->opcode == ZEND_MATCH_ERROR
|
||||||
|| opline->opcode == ZEND_FETCH_LIST_R
|
|| opline->opcode == ZEND_FETCH_LIST_R
|
||||||
|| opline->opcode == ZEND_FETCH_LIST_W
|
|| opline->opcode == ZEND_FETCH_LIST_W
|
||||||
|| opline->opcode == ZEND_COPY_TMP) {
|
|| opline->opcode == ZEND_COPY_TMP) {
|
||||||
|
|||||||
21
ext/opcache/tests/gh17106.phpt
Normal file
21
ext/opcache/tests/gh17106.phpt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
--TEST--
|
||||||
|
GH-17106: ZEND_MATCH_ERROR misoptimization
|
||||||
|
--EXTENSIONS--
|
||||||
|
opcache
|
||||||
|
--INI--
|
||||||
|
opcache.enable_cli=1
|
||||||
|
opcache.optimization_level=-1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
const X = 2;
|
||||||
|
|
||||||
|
var_dump(7 ?? match (X) {});
|
||||||
|
var_dump(null ?? match (X) { 2 => 2 });
|
||||||
|
var_dump(match (X) { 2 => 2 });
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(7)
|
||||||
|
int(2)
|
||||||
|
int(2)
|
||||||
Reference in New Issue
Block a user