diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2018-03-13 10:47:11 +0300 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2018-03-13 10:47:11 +0300 |
| commit | 1c3796b751e508e1e2e8084e11702cc9daa6c1b0 (patch) | |
| tree | 3572c5182e6760dc2eb9ad3b8b52339a62c5cb3e | |
| parent | c305dbacc8b59adbafad3360bf239b656ada7e83 (diff) | |
| parent | 575f5002c023c0bf95b86941bb796c080580f770 (diff) | |
| download | php-git-1c3796b751e508e1e2e8084e11702cc9daa6c1b0.tar.gz | |
Merge branch 'PHP-7.2'
* PHP-7.2:
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 c3cbef84cd..63964f6280 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 { |
