diff options
author | Dmitry Stogov <dmitry@zend.com> | 2018-03-13 10:45:53 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2018-03-13 10:45:53 +0300 |
commit | 575f5002c023c0bf95b86941bb796c080580f770 (patch) | |
tree | 8c6cfddb1b443ff02d74543eb1b65e9fadd37f25 | |
parent | 98fe858275af3cf780ee6ae79acd9cddd92b5460 (diff) | |
parent | 44ba557de5c0d767ff6ccfcc2c8bde7d7c0746fe (diff) | |
download | php-git-575f5002c023c0bf95b86941bb796c080580f770.tar.gz |
Merge branch 'PHP-7.1' into PHP-7.2
* PHP-7.1:
More accurate symbolic constraints oferflow/unserflow handling (better fix for bug #76074).
-rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index facfc6bede..c9ffd86c83 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -159,15 +159,12 @@ } while (0) static inline zend_bool add_will_overflow(zend_long a, zend_long b) { - return (b > 0 && a > ZEND_LONG_MAX - b) - || (b < 0 && a < ZEND_LONG_MIN - b); + return (b > 0 && a > ZEND_LONG_MAX - b); } -#if 0 -static inline zend_bool sub_will_overflow(zend_long a, zend_long b) { - return (b > 0 && a < ZEND_LONG_MIN + b) - || (b < 0 && a > ZEND_LONG_MAX + b); + +static inline zend_bool add_will_underflow(zend_long a, zend_long b) { + return (b < 0 && a < ZEND_LONG_MIN - b); } -#endif static void zend_ssa_check_scc_var(const zend_op_array *op_array, zend_ssa *ssa, int var, int *index, int *dfs, int *root, zend_worklist_stack *stack) /* {{{ */ { @@ -904,8 +901,13 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int tmp->min = MAX(constraint->range.min, tmp->min); #ifdef SYM_RANGE } else if (narrowing && ssa->var_info[constraint->min_ssa_var].has_range) { - tmp->underflow = ssa->var_info[constraint->min_ssa_var].range.underflow && tmp->underflow; - if (!add_will_overflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) { + if ((ssa->var_info[constraint->min_ssa_var].range.underflow + || add_will_underflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) + && tmp->underflow) { + tmp->underflow = 1; + tmp->min = ZEND_LONG_MIN; + } else { + tmp->underflow = 0; tmp->min = MAX(ssa->var_info[constraint->min_ssa_var].range.min + constraint->range.min, tmp->min); } #endif @@ -915,10 +917,15 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int tmp->overflow = constraint->range.overflow && tmp->overflow; #ifdef SYM_RANGE } else if (narrowing && ssa->var_info[constraint->max_ssa_var].has_range) { - if (!add_will_overflow(ssa->var_info[constraint->max_ssa_var].range.max, constraint->range.max)) { + if ((ssa->var_info[constraint->min_ssa_var].range.overflow + || add_will_overflow(ssa->var_info[constraint->min_ssa_var].range.max, constraint->range.max)) + && tmp->overflow) { + tmp->overflow = 1; + tmp->max = ZEND_LONG_MAX; + } else { + tmp->overflow = 0; tmp->max = MIN(ssa->var_info[constraint->max_ssa_var].range.max + constraint->range.max, tmp->max); } - tmp->overflow = ssa->var_info[constraint->max_ssa_var].range.overflow && tmp->overflow; #endif } } else if (narrowing) { @@ -927,7 +934,7 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int tmp->min = constraint->range.min; #ifdef SYM_RANGE } else if (narrowing && ssa->var_info[constraint->min_ssa_var].has_range) { - if (add_will_overflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) { + if (add_will_underflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) { tmp->underflow = 1; tmp->min = ZEND_LONG_MIN; } else { |