Skip to content

Commit

Permalink
More accurate symbolic constraints oferflow/unserflow handling (bette…
Browse files Browse the repository at this point in the history
…r fix for bug #76074).
  • Loading branch information
dstogov committed Mar 13, 2018
1 parent 998a2dd commit 44ba557
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions ext/opcache/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,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) /* {{{ */
{
Expand Down Expand Up @@ -836,8 +833,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
Expand All @@ -847,10 +849,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) {
Expand All @@ -859,7 +866,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 {
Expand Down

0 comments on commit 44ba557

Please sign in to comment.