From d0860f67ca52ea25ddfac5ea663389bbbb3b75f9 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Sep 2021 14:32:49 +0200 Subject: [PATCH] Fix cache slot assignment for ASSIGN_OBJ_OP ASSIGN_OBJ_OP stores the cache slot in OP_DATA, so this ended up overwriting the binop opcode instread. --- Zend/tests/assign_obj_op_cache_slot.phpt | 14 ++++++++++++++ ext/opcache/Optimizer/zend_optimizer.c | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/assign_obj_op_cache_slot.phpt diff --git a/Zend/tests/assign_obj_op_cache_slot.phpt b/Zend/tests/assign_obj_op_cache_slot.phpt new file mode 100644 index 00000000000..6cf6939b043 --- /dev/null +++ b/Zend/tests/assign_obj_op_cache_slot.phpt @@ -0,0 +1,14 @@ +--TEST-- +The ASSIGN_OBJ_OP cache slot is on the OP_DATA opcode +--FILE-- +$b = 1; + $a->$b &= 1; + var_dump($a->$b); +} +test(new stdClass); +?> +--EXPECT-- +int(1) diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index c80992ed8da..62c32a5858c 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -451,11 +451,16 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: - case ZEND_ASSIGN_OBJ_OP: TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); opline->extended_value = alloc_cache_slots(op_array, 3); break; + case ZEND_ASSIGN_OBJ_OP: + TO_STRING_NOWARN(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + ZEND_ASSERT((opline + 1)->opcode == ZEND_OP_DATA); + (opline + 1)->extended_value = alloc_cache_slots(op_array, 3); + break; case ZEND_ISSET_ISEMPTY_PROP_OBJ: TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val);