]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4' into PHP-8.0
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Nov 2020 09:20:23 +0000 (10:20 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Nov 2020 09:20:23 +0000 (10:20 +0100)
* PHP-7.4:
  Fix incorrectly optimized out live range

1  2 
ext/opcache/Optimizer/zend_optimizer.c

index b0efcc902602d1234a07b99ddbcb91012df1fcb9,7871fa3c8e042a85732039053482878590598a93..c80992ed8dae041e863968fff4fdac3a702460cd
@@@ -1350,14 -1312,25 +1350,24 @@@ static void zend_adjust_fcall_stack_siz
  static zend_bool needs_live_range(zend_op_array *op_array, zend_op *def_opline) {
        zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
        zend_ssa_op *ssa_op = &func_info->ssa.ops[def_opline - op_array->opcodes];
-       if (ssa_op->result_def >= 0) {
-               uint32_t type = func_info->ssa.var_info[ssa_op->result_def].type;
-               return (type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) != 0;
+       int ssa_var = ssa_op->result_def;
+       if (ssa_var < 0) {
+               /* Be conservative. */
+               return 1;
        }
-       return 1;
+       /* If the variable is used by a PHI, this may be the assignment of the final branch of a
+        * ternary/etc structure. While this is where the live range starts, the value from the other
+        * branch may also be used. As such, use the type of the PHI node for the following check. */
+       if (func_info->ssa.vars[ssa_var].phi_use_chain) {
+               ssa_var = func_info->ssa.vars[ssa_var].phi_use_chain->ssa_var;
+       }
+       uint32_t type = func_info->ssa.var_info[ssa_var].type;
+       return (type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) != 0;
  }
 -#endif
  
 -int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level)
 +void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context)
  {
        zend_class_entry *ce;
        zend_string *key;