@@ -875,8 +875,50 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
875
875
if (p -> pi >= 0 && p -> has_range_constraint ) {
876
876
zend_ssa_range_constraint * constraint = & p -> constraint .range ;
877
877
if (constraint -> negative ) {
878
- if (ssa -> var_info [p -> sources [0 ]].has_range ) {
879
- * tmp = ssa -> var_info [p -> sources [0 ]].range ;
878
+ int src1 = p -> sources [0 ];
879
+
880
+ if (ssa -> var_info [src1 ].has_range ) {
881
+ * tmp = ssa -> var_info [src1 ].range ;
882
+ if (constraint -> range .min == constraint -> range .max
883
+ && !constraint -> range .underflow
884
+ && !constraint -> range .overflow
885
+ && p -> constraint .range .min_ssa_var < 0
886
+ && p -> constraint .range .max_ssa_var < 0
887
+ && ssa -> vars [src1 ].definition >= 0 ) {
888
+ /* Check for constrained induction variable */
889
+ line = ssa -> vars [src1 ].definition ;
890
+ opline = op_array -> opcodes + line ;
891
+ switch (opline -> opcode ) {
892
+ case ZEND_PRE_DEC :
893
+ case ZEND_POST_DEC :
894
+ if (!tmp -> underflow ) {
895
+ zend_ssa_phi * p = ssa -> vars [ssa -> ops [line ].op1_use ].definition_phi ;
896
+
897
+ if (p && p -> pi < 0
898
+ && ssa -> cfg .blocks [p -> block ].predecessors_count == 2
899
+ && p -> sources [1 ] == var
900
+ && ssa -> var_info [p -> sources [0 ]].has_range
901
+ && ssa -> var_info [p -> sources [0 ]].range .min > constraint -> range .max ) {
902
+ tmp -> min = constraint -> range .max + 1 ;
903
+ }
904
+ }
905
+ break ;
906
+ case ZEND_PRE_INC :
907
+ case ZEND_POST_INC :
908
+ if (!tmp -> overflow ) {
909
+ zend_ssa_phi * p = ssa -> vars [ssa -> ops [line ].op1_use ].definition_phi ;
910
+
911
+ if (p && p -> pi < 0
912
+ && ssa -> cfg .blocks [p -> block ].predecessors_count == 2
913
+ && p -> sources [1 ] == var
914
+ && ssa -> var_info [p -> sources [0 ]].has_range
915
+ && ssa -> var_info [p -> sources [0 ]].range .max < constraint -> range .min ) {
916
+ tmp -> max = constraint -> range .min - 1 ;
917
+ }
918
+ }
919
+ break ;
920
+ }
921
+ }
880
922
} else if (narrowing ) {
881
923
tmp -> underflow = 1 ;
882
924
tmp -> min = ZEND_LONG_MIN ;
0 commit comments