uint32_t line;
zend_op *opline;
zend_ssa_op *ssa_op;
- zend_long op1_min, op2_min, op1_max, op2_max;
if (ssa->vars[var].definition_phi) {
zend_ssa_phi *p = ssa->vars[var].definition_phi;
opline = op_array->opcodes + line;
ssa_op = &ssa->ops[line];
+ return zend_inference_propagate_range(op_array, ssa, opline, ssa_op, var, tmp);
+}
+
+int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp)
+{
+ zend_long op1_min, op2_min, op1_max, op2_max;
+
tmp->underflow = 0;
tmp->overflow = 0;
switch (opline->opcode) {
uint32_t zend_array_element_type(uint32_t t1, zend_uchar op_type, int write, int insert);
int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int var, int widening, int narrowing, zend_ssa_range *tmp);
+int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp);
void zend_inference_init_range(const zend_op_array *op_array, zend_ssa *ssa, int var, zend_bool underflow, zend_long min, zend_long max, zend_bool overflow);
int zend_inference_narrowing_meet(zend_ssa_var_info *var_info, zend_ssa_range *r);
int zend_inference_widening_meet(zend_ssa_var_info *var_info, zend_ssa_range *r);
}
if (ssa_op) {
+ zend_ssa_range tmp;
+
/* Keep information about known types on abstract stack */
if (ssa_op->result_def >= 0) {
zend_uchar type = IS_UNKNOWN;
}
}
}
+
+ if (type == IS_LONG
+ && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->result_def, &tmp)) {
+ ssa->var_info[ssa_op->result_def].range.min = tmp.min;
+ ssa->var_info[ssa_op->result_def].range.max = tmp.max;
+ ssa->var_info[ssa_op->result_def].range.underflow = 0;
+ ssa->var_info[ssa_op->result_def].range.overflow = 0;
+ ssa->var_info[ssa_op->result_def].has_range = 1;
+ }
}
if (ssa_op->op1_def >= 0) {
zend_uchar type = IS_UNKNOWN;
ra[ssa_op->op1_def]->flags & ZREG_STORE);
}
}
+ if (type == IS_LONG
+ && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->op1_def, &tmp)) {
+ ssa->var_info[ssa_op->op1_def].range.min = tmp.min;
+ ssa->var_info[ssa_op->op1_def].range.max = tmp.max;
+ ssa->var_info[ssa_op->op1_def].range.underflow = 0;
+ ssa->var_info[ssa_op->op1_def].range.overflow = 0;
+ ssa->var_info[ssa_op->op1_def].has_range = 1;
+ }
}
if (ssa_op->op2_def >= 0) {
zend_uchar type = IS_UNKNOWN;
ra[ssa_op->op2_def]->flags & ZREG_STORE);
}
}
+ if (type == IS_LONG
+ && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->op2_def, &tmp)) {
+ ssa->var_info[ssa_op->op2_def].range.min = tmp.min;
+ ssa->var_info[ssa_op->op2_def].range.max = tmp.max;
+ ssa->var_info[ssa_op->op2_def].range.underflow = 0;
+ ssa->var_info[ssa_op->op2_def].range.overflow = 0;
+ ssa->var_info[ssa_op->op2_def].has_range = 1;
+ }
}
switch (opline->opcode) {
ra[ssa_op->op1_def]->reg & ZREG_STORE);
}
}
+ if (type == IS_LONG
+ && zend_inference_propagate_range(op_array, ssa, (zend_op*)opline, (zend_ssa_op*)ssa_op, ssa_op->op1_def, &tmp)) {
+ ssa->var_info[ssa_op->op1_def].range.min = tmp.min;
+ ssa->var_info[ssa_op->op1_def].range.max = tmp.max;
+ ssa->var_info[ssa_op->op1_def].range.underflow = 0;
+ ssa->var_info[ssa_op->op1_def].range.overflow = 0;
+ ssa->var_info[ssa_op->op1_def].has_range = 1;
+ }
}
ssa_op++;
break;