]> granicus.if.org Git - php/commitdiff
Improve fix for bug #75687
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 16 Dec 2017 20:11:40 +0000 (21:11 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Sat, 16 Dec 2017 20:11:40 +0000 (21:11 +0100)
Adding an (incorrect) UNDEF here may cause subsequent narrowing in
other places.

Instead, let's try to handle this edge-case once for all
instructions...

ext/opcache/Optimizer/zend_inference.c

index 263df059f033e84e5610f2e77f16678c020a7848..c049ca3c98409e8086859f22c864670a086e07a9 100644 (file)
@@ -2154,6 +2154,24 @@ static int zend_update_type_info(const zend_op_array *op_array,
        t1 = OP1_INFO();
        t2 = OP2_INFO();
 
+       /* If one of the operands cannot have any type, this means the operand derives from
+        * unreachable code. Propagate the empty result early, so that that the following
+        * code may assume that operands have at least one type. */
+       if (!(t1 & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_CLASS|MAY_BE_ERROR))
+                       || !(t2 & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_CLASS|MAY_BE_ERROR))) {
+               tmp = 0;
+               if (ssa_ops[i].result_def >= 0) {
+                       UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
+               } 
+               if (ssa_ops[i].op1_def >= 0) { 
+                       UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
+               } 
+               if (ssa_ops[i].op2_def >= 0) { 
+                       UPDATE_SSA_TYPE(tmp, ssa_ops[i].op2_def);
+               } 
+               return 1;
+       } 
+
        switch (opline->opcode) {
                case ZEND_ADD:
                case ZEND_SUB:
@@ -3338,9 +3356,6 @@ int zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script
                                                        /* Ignore the constraint (either ce instanceof constraint->ce or
                                                         * they are unrelated, as far as we can statically determine) */
                                                }
-                                       } else if ((tmp & MAY_BE_ANY) == 0) {
-                                               /* FIXME: usage in unreachable block */
-                                               tmp |= MAY_BE_UNDEF;
                                        }
                                }