Make sure that the previous opline is part of the same block,
otherwise it may be non-dominating.

The test case does not fail on PHP-7.4, but I think the general
problem can appear on 7.4 as well, so I'm applying the patch to
that branch.
This commit is contained in:
Nikita Popov 2021-05-06 10:42:03 +02:00
parent 896e4d3428
commit 178bbe3478
3 changed files with 36 additions and 0 deletions

2
NEWS
View File

@ -34,6 +34,8 @@ PHP NEWS
- Opcache:
. Fixed bug #80900 (switch statement behavior inside function). (twosee)
. Fixed bug #81015 (Opcache optimization assumes wrong part of ternary
operator in if-condition). (Nikita)
- XMLReader:
. Fixed bug #73246 (XMLReader: encoding length not checked). (cmb)

View File

@ -255,6 +255,14 @@ static void place_essa_pis(
default:
continue;
}
/* The following patterns all inspect the opline directly before the JMPZ opcode.
* Make sure that it is part of the same block, otherwise it might not be a dominating
* assignment. */
if (blocks[j].len == 1) {
continue;
}
if (opline->op1_type == IS_TMP_VAR &&
((opline-1)->opcode == ZEND_IS_EQUAL ||
(opline-1)->opcode == ZEND_IS_NOT_EQUAL ||

View File

@ -0,0 +1,26 @@
--TEST--
Bug #81015: Opcache optimization assumes wrong part of ternary operator in if-condition
--FILE--
<?php
function ternary(bool $enabled, ?string $value): void
{
// the "true" part is not as trivial in the real case
if ($enabled ? true : $value === null) {
echo ($value ?? 'NULL') . "\n";
} else {
echo "INVALID\n";
}
}
ternary(true, 'value');
ternary(true, null);
ternary(false, 'value');
ternary(false, null);
?>
--EXPECT--
value
NULL
INVALID
NULL