diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 61a69dae51e1..0a1662abdbdd 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -703,7 +703,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } else if (opline->op1_type == IS_TMP_VAR && !zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) { src = VAR_SOURCE(opline->op1); - if (src) { + if (src && src->op1_type != IS_VAR) { if (src->opcode == ZEND_BOOL_NOT) { VAR_SOURCE(opline->op1) = NULL; COPY_NODE(opline->op1, src->op1); @@ -747,7 +747,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array (!zend_bitset_in(used_ext, VAR_NUM(opline->op1.var)) || opline->result.var == opline->op1.var)) { src = VAR_SOURCE(opline->op1); - if (src) { + if (src && src->op1_type != IS_VAR) { if (src->opcode == ZEND_BOOL || src->opcode == ZEND_QM_ASSIGN) { VAR_SOURCE(opline->op1) = NULL; diff --git a/ext/opcache/tests/gh21691.phpt b/ext/opcache/tests/gh21691.phpt new file mode 100644 index 000000000000..71bf6786f6de --- /dev/null +++ b/ext/opcache/tests/gh21691.phpt @@ -0,0 +1,42 @@ +--TEST-- +GH-21691 (OPcache CFG optimizer breaks reference returns with JMPZ/JMPZ_EX) +--INI-- +opcache.enable_cli=1 +--EXTENSIONS-- +opcache +--FILE-- +getData() && !isset($data['key'])) { + } + return $data; + } + + public function check(): bool { + return ($data = &$this->getData()) && count($data) > 0; + } +} + +class Child extends Base { + protected function &getData(): array { + static $x = ['value' => 42]; + return $x; + } +} + +$child = new Child(); +var_dump($child->process()); +var_dump($child->check()); +?> +--EXPECT-- +array(1) { + ["value"]=> + int(42) +} +bool(true)