]> granicus.if.org Git - php/commitdiff
Fix another bug in coalesce elimination
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 17 Feb 2018 11:59:25 +0000 (12:59 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Sat, 17 Feb 2018 13:51:11 +0000 (14:51 +0100)
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/tests/jmp_elim_004.phpt

index 9e16a9c55c9e2d47f1edd4b123363c9eac390c8a..ae067c58eb3ef4135753d4d1b4864692c44f3e4c 100644 (file)
@@ -810,28 +810,30 @@ optimize_jmpnz:
                                        }
                                        break;
                                case ZEND_COALESCE:
-                                       if (opline->op1_type == IS_CONST) {
+                               {
+                                       zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
+                                       if (opline->op1_type == IS_CONST
+                                                       && var->use_chain < 0 && var->phi_use_chain == NULL) {
                                                if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op1.constant)) == IS_NULL) {
+                                                       zend_ssa_remove_result_def(ssa, ssa_op);
                                                        MAKE_NOP(opline);
                                                        removed_ops++;
                                                        take_successor_1(ssa, block_num, block);
                                                        goto optimize_nop;
                                                } else {
-                                                       zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
-                                                       if (var->use_chain < 0 && var->phi_use_chain == NULL) {
-                                                               if (opline->result_type & (IS_TMP_VAR|IS_VAR)) {
-                                                                       zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition);
-                                                               }
-                                                               opline->opcode = ZEND_JMP;
-                                                               opline->result_type = IS_UNUSED;
-                                                               zend_ssa_remove_result_def(ssa, ssa_op);
-                                                               COPY_NODE(opline->op1, opline->op2);
-                                                               take_successor_0(ssa, block_num, block);
-                                                               goto optimize_jmp;
+                                                       if (opline->result_type & (IS_TMP_VAR|IS_VAR)) {
+                                                               zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition);
                                                        }
+                                                       opline->opcode = ZEND_JMP;
+                                                       opline->result_type = IS_UNUSED;
+                                                       zend_ssa_remove_result_def(ssa, ssa_op);
+                                                       COPY_NODE(opline->op1, opline->op2);
+                                                       take_successor_0(ssa, block_num, block);
+                                                       goto optimize_jmp;
                                                }
                                        }
                                        break;
+                               }
                                case ZEND_NOP:
 optimize_nop:
                                        compress_block(op_array, block);
index e31af3da17b9fcc356eae5a0c2814d12c89bf35d..f4053d9616b4f7016f9376b6f288b1d5b7a48ce6 100644 (file)
@@ -9,9 +9,16 @@ opcache.optimization_level=-1
 function test() {
     $foo = "test";
     var_dump($foo ?? "default");
+
+    $null = null;
+    var_dump($null ?? 3);
+    var_dump($null ?? new stdClass);
 }
 test();
 
 ?>
 --EXPECT--
 string(4) "test"
+int(3)
+object(stdClass)#1 (0) {
+}