diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 61a69dae51e1a..704a16b3ae668 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -714,6 +714,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array continue; } else if (src->opcode == ZEND_BOOL || src->opcode == ZEND_QM_ASSIGN) { + if (src->op1_type == IS_VAR) { + break; + } VAR_SOURCE(opline->op1) = NULL; COPY_NODE(opline->op1, src->op1); MAKE_NOP(src); diff --git a/ext/opcache/tests/gh21691.phpt b/ext/opcache/tests/gh21691.phpt new file mode 100644 index 0000000000000..0956a0d62816a --- /dev/null +++ b/ext/opcache/tests/gh21691.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21691 (OPcache CFG optimizer breaks reference returns with JMPZ) +--INI-- +opcache.enable_cli=1 +--EXTENSIONS-- +opcache +--FILE-- +getData() && !isset($data['key'])) { + } + return $data; + } +} + +class Child extends Base { + protected function &getData(): array { + static $x = ['value' => 42]; + return $x; + } +} + +$child = new Child(); +var_dump($child->process()); +?> +--EXPECT-- +array(1) { + ["value"]=> + int(42) +}