Skip to content

Commit 575f500

Browse files
committed
Merge branch 'PHP-7.1' into PHP-7.2
* PHP-7.1: More accurate symbolic constraints oferflow/unserflow handling (better fix for bug #76074).
2 parents 98fe858 + 44ba557 commit 575f500

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

ext/opcache/Optimizer/zend_inference.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,12 @@
159159
} while (0)
160160

161161
static inline zend_bool add_will_overflow(zend_long a, zend_long b) {
162-
return (b > 0 && a > ZEND_LONG_MAX - b)
163-
|| (b < 0 && a < ZEND_LONG_MIN - b);
162+
return (b > 0 && a > ZEND_LONG_MAX - b);
164163
}
165-
#if 0
166-
static inline zend_bool sub_will_overflow(zend_long a, zend_long b) {
167-
return (b > 0 && a < ZEND_LONG_MIN + b)
168-
|| (b < 0 && a > ZEND_LONG_MAX + b);
164+
165+
static inline zend_bool add_will_underflow(zend_long a, zend_long b) {
166+
return (b < 0 && a < ZEND_LONG_MIN - b);
169167
}
170-
#endif
171168

172169
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) /* {{{ */
173170
{
@@ -904,8 +901,13 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
904901
tmp->min = MAX(constraint->range.min, tmp->min);
905902
#ifdef SYM_RANGE
906903
} else if (narrowing && ssa->var_info[constraint->min_ssa_var].has_range) {
907-
tmp->underflow = ssa->var_info[constraint->min_ssa_var].range.underflow && tmp->underflow;
908-
if (!add_will_overflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) {
904+
if ((ssa->var_info[constraint->min_ssa_var].range.underflow
905+
|| add_will_underflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min))
906+
&& tmp->underflow) {
907+
tmp->underflow = 1;
908+
tmp->min = ZEND_LONG_MIN;
909+
} else {
910+
tmp->underflow = 0;
909911
tmp->min = MAX(ssa->var_info[constraint->min_ssa_var].range.min + constraint->range.min, tmp->min);
910912
}
911913
#endif
@@ -915,10 +917,15 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
915917
tmp->overflow = constraint->range.overflow && tmp->overflow;
916918
#ifdef SYM_RANGE
917919
} else if (narrowing && ssa->var_info[constraint->max_ssa_var].has_range) {
918-
if (!add_will_overflow(ssa->var_info[constraint->max_ssa_var].range.max, constraint->range.max)) {
920+
if ((ssa->var_info[constraint->min_ssa_var].range.overflow
921+
|| add_will_overflow(ssa->var_info[constraint->min_ssa_var].range.max, constraint->range.max))
922+
&& tmp->overflow) {
923+
tmp->overflow = 1;
924+
tmp->max = ZEND_LONG_MAX;
925+
} else {
926+
tmp->overflow = 0;
919927
tmp->max = MIN(ssa->var_info[constraint->max_ssa_var].range.max + constraint->range.max, tmp->max);
920928
}
921-
tmp->overflow = ssa->var_info[constraint->max_ssa_var].range.overflow && tmp->overflow;
922929
#endif
923930
}
924931
} else if (narrowing) {
@@ -927,7 +934,7 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
927934
tmp->min = constraint->range.min;
928935
#ifdef SYM_RANGE
929936
} else if (narrowing && ssa->var_info[constraint->min_ssa_var].has_range) {
930-
if (add_will_overflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) {
937+
if (add_will_underflow(ssa->var_info[constraint->min_ssa_var].range.min, constraint->range.min)) {
931938
tmp->underflow = 1;
932939
tmp->min = ZEND_LONG_MIN;
933940
} else {

0 commit comments

Comments
 (0)