From 178bbe3478a3aa6aeb6eeae62950d8a5203d794b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 6 May 2021 10:42:03 +0200 Subject: [PATCH] Fixed bug #81015 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. --- NEWS | 2 ++ ext/opcache/Optimizer/zend_ssa.c | 8 ++++++++ ext/opcache/tests/bug81015.phpt | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 ext/opcache/tests/bug81015.phpt diff --git a/NEWS b/NEWS index 41ceb1dc420..a5d9a356d32 100644 --- a/NEWS +++ b/NEWS @@ -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) diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index 0b8c76d3ac2..1ea335c4a6d 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -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 || diff --git a/ext/opcache/tests/bug81015.phpt b/ext/opcache/tests/bug81015.phpt new file mode 100644 index 00000000000..b5009e6a236 --- /dev/null +++ b/ext/opcache/tests/bug81015.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #81015: Opcache optimization assumes wrong part of ternary operator in if-condition +--FILE-- + +--EXPECT-- +value +NULL +INVALID +NULL