op2_min = OP2_MIN_RANGE();
op1_max = OP1_MAX_RANGE();
op2_max = OP2_MAX_RANGE();
- tmp->min = op1_min + op2_min;
- tmp->max = op1_max + op2_max;
if (OP1_RANGE_UNDERFLOW() ||
OP2_RANGE_UNDERFLOW() ||
- (op1_min < 0 && op2_min < 0 && tmp->min >= 0)) {
+ zend_add_will_overflow(op1_min, op2_min)) {
tmp->underflow = 1;
tmp->min = ZEND_LONG_MIN;
+ } else {
+ tmp->min = op1_min + op2_min;
}
if (OP1_RANGE_OVERFLOW() ||
OP2_RANGE_OVERFLOW() ||
- (op1_max > 0 && op2_max > 0 && tmp->max <= 0)) {
+ zend_add_will_overflow(op1_max, op2_max)) {
tmp->overflow = 1;
tmp->max = ZEND_LONG_MAX;
+ } else {
+ tmp->max = op1_max + op2_max;
}
return 1;
}
op2_min = OP2_MIN_RANGE();
op1_max = OP1_MAX_RANGE();
op2_max = OP2_MAX_RANGE();
- tmp->min = op1_min - op2_max;
- tmp->max = op1_max - op2_min;
if (OP1_RANGE_UNDERFLOW() ||
OP2_RANGE_OVERFLOW() ||
- (op1_min < 0 && op2_max > 0 && tmp->min >= 0)) {
+ zend_sub_will_overflow(op1_min, op2_max)) {
tmp->underflow = 1;
tmp->min = ZEND_LONG_MIN;
+ } else {
+ tmp->min = op1_min - op2_max;
}
if (OP1_RANGE_OVERFLOW() ||
OP2_RANGE_UNDERFLOW() ||
- (op1_max > 0 && op2_min < 0 && tmp->max <= 0)) {
+ zend_sub_will_overflow(op1_max, op2_min)) {
tmp->overflow = 1;
tmp->max = ZEND_LONG_MAX;
+ } else {
+ tmp->max = op1_max - op2_min;
}
return 1;
}
}
/* }}} */
-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);
-}
-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);
-}
-
/* e-SSA construction: Pi placement (Pi is actually a Phi with single
* source and constraint).
* Order of Phis is importent, Pis must be placed before Phis
}
if (var1 >= 0 && var2 >= 0) {
- if (!sub_will_overflow(val1, val2) && !sub_will_overflow(val2, val1)) {
+ if (!zend_sub_will_overflow(val1, val2) && !zend_sub_will_overflow(val2, val1)) {
zend_long tmp = val1;
val1 -= val2;
val2 -= tmp;
} else {
var1 = -1;
}
- if (!add_will_overflow(val2, add_val2)) {
+ if (!zend_add_will_overflow(val2, add_val2)) {
val2 += add_val2;
} else {
var1 = -1;
} else {
var2 = -1;
}
- if (!add_will_overflow(val1, add_val1)) {
+ if (!zend_add_will_overflow(val1, add_val1)) {
val1 += add_val1;
} else {
var2 = -1;
return 1;
}
if (ssa->var_info[res].range.underflow) {
- zend_long op1_min, op2_min, res_min;
+ zend_long op1_min, op2_min;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_min = OP1_MIN_RANGE();
op2_min = OP2_MIN_RANGE();
- res_min = op1_min + op2_min;
- if (op1_min < 0 && op2_min < 0 && res_min >= 0) {
+ if (zend_add_will_overflow(op1_min, op2_min)) {
return 1;
}
}
if (ssa->var_info[res].range.overflow) {
- zend_long op1_max, op2_max, res_max;
+ zend_long op1_max, op2_max;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_max = OP2_MAX_RANGE();
- res_max = op1_max + op2_max;
- if (op1_max > 0 && op2_max > 0 && res_max <= 0) {
+ if (zend_add_will_overflow(op1_max, op2_max)) {
return 1;
}
}
return 1;
}
if (ssa->var_info[res].range.underflow) {
- zend_long op1_min, op2_max, res_min;
+ zend_long op1_min, op2_max;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_min = OP1_MIN_RANGE();
op2_max = OP2_MAX_RANGE();
- res_min = op1_min - op2_max;
- if (op1_min < 0 && op2_max > 0 && res_min >= 0) {
+ if (zend_sub_will_overflow(op1_min, op2_max)) {
return 1;
}
}
if (ssa->var_info[res].range.overflow) {
- zend_long op1_max, op2_min, res_max;
+ zend_long op1_max, op2_min;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_min = OP2_MIN_RANGE();
- res_max = op1_max - op2_min;
- if (op1_max > 0 && op2_min < 0 && res_max <= 0) {
+ if (zend_sub_will_overflow(op1_max, op2_min)) {
return 1;
}
}
return 1;
}
if (ssa->var_info[res].range.underflow) {
- zend_long op1_min, op2_min, res_min;
+ zend_long op1_min, op2_min;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_min = OP1_MIN_RANGE();
op2_min = OP2_MIN_RANGE();
- res_min = op1_min + op2_min;
- if (op1_min < 0 && op2_min < 0 && res_min >= 0) {
+ if (zend_add_will_overflow(op1_min, op2_min)) {
return 1;
}
}
if (ssa->var_info[res].range.overflow) {
- zend_long op1_max, op2_max, res_max;
+ zend_long op1_max, op2_max;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_max = OP2_MAX_RANGE();
- res_max = op1_max + op2_max;
- if (op1_max > 0 && op2_max > 0 && res_max <= 0) {
+ if (zend_add_will_overflow(op1_max, op2_max)) {
return 1;
}
}
return 1;
}
if (ssa->var_info[res].range.underflow) {
- zend_long op1_min, op2_max, res_min;
+ zend_long op1_min, op2_max;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_min = OP1_MIN_RANGE();
op2_max = OP2_MAX_RANGE();
- res_min = op1_min - op2_max;
- if (op1_min < 0 && op2_max > 0 && res_min >= 0) {
+ if (zend_sub_will_overflow(op1_min, op2_max)) {
return 1;
}
}
if (ssa->var_info[res].range.overflow) {
- zend_long op1_max, op2_min, res_max;
+ zend_long op1_max, op2_min;
if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
return 1;
}
op1_max = OP1_MAX_RANGE();
op2_min = OP2_MIN_RANGE();
- res_max = op1_max - op2_min;
- if (op1_max > 0 && op2_min < 0 && res_max <= 0) {
+ if (zend_sub_will_overflow(op1_max, op2_min)) {
return 1;
}
}