Handle SWITCH_STRING with optimized away FREE

This can happen in degenerate cases where we know that the
SWITCH_STRING argument is not refcounted. We should be treating it
in the same way as SWITCH_LONG here.
This commit is contained in:
Nikita Popov 2021-09-16 11:31:06 +02:00
parent 236e7aef01
commit 7257e7e5aa
2 changed files with 17 additions and 2 deletions

View File

@ -767,13 +767,13 @@ static zend_bool keeps_op1_alive(zend_op *opline) {
if (opline->opcode == ZEND_CASE
|| opline->opcode == ZEND_CASE_STRICT
|| opline->opcode == ZEND_SWITCH_LONG
|| opline->opcode == ZEND_SWITCH_STRING
|| opline->opcode == ZEND_MATCH
|| opline->opcode == ZEND_FETCH_LIST_R
|| opline->opcode == ZEND_COPY_TMP) {
return 1;
}
ZEND_ASSERT(opline->opcode != ZEND_SWITCH_STRING
&& opline->opcode != ZEND_FE_FETCH_R
ZEND_ASSERT(opline->opcode != ZEND_FE_FETCH_R
&& opline->opcode != ZEND_FE_FETCH_RW
&& opline->opcode != ZEND_FETCH_LIST_W
&& opline->opcode != ZEND_VERIFY_RETURN_TYPE

View File

@ -0,0 +1,15 @@
--TEST--
A SWITCH_STRING operand FREE may be optimized away
--FILE--
<?php
function test($a) {
switch (!$a) {
case '':
r>l;
default:
}
}
?>
===DONE===
--EXPECT--
===DONE===