@@ -122,7 +122,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex
122122 /* Vars */
123123 for (i = 0 ; i < ssa -> vars_count ; i ++ ) {
124124 zend_ssa_var * var = & ssa -> vars [i ];
125- int use , c ;
125+ int use ;
126126 uint32_t type = ssa -> var_info [i ].type ;
127127
128128 if (var -> definition < 0 && !var -> definition_phi && i > op_array -> last_var ) {
@@ -148,23 +148,45 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex
148148 }
149149 }
150150
151- c = 0 ;
152- FOREACH_USE (var , use ) {
153- if (++ c > 10000 ) {
151+ /* Floyd's cycle detection algorithm, applied for use chain. */
152+ use = var -> use_chain ;
153+ int second_use = use ;
154+ while (use >= 0 && second_use >= 0 ) {
155+ use = zend_ssa_next_use (ssa -> ops , var - ssa -> vars , use );
156+ second_use = zend_ssa_next_use (ssa -> ops , var - ssa -> vars , second_use );
157+ if (second_use < 0 ) {
158+ break ;
159+ }
160+ second_use = zend_ssa_next_use (ssa -> ops , var - ssa -> vars , second_use );
161+ if (use == second_use ) {
154162 FAIL ("cycle in uses of " VARFMT "\n" , VAR (i ));
155163 goto finish ;
156164 }
165+ }
166+
167+ FOREACH_USE (var , use ) {
157168 if (!is_used_by_op (ssa , use , i )) {
158169 fprintf (stderr , "var " VARFMT " not in uses of op %d\n" , VAR (i ), use );
159170 }
160171 } FOREACH_USE_END ();
161172
162- c = 0 ;
163- FOREACH_PHI_USE (var , phi ) {
164- if (++ c > 10000 ) {
173+ /* Floyd's cycle detection algorithm, applied for phi nodes. */
174+ phi = var -> phi_use_chain ;
175+ zend_ssa_phi * second_phi = phi ;
176+ while (phi && second_phi ) {
177+ phi = zend_ssa_next_use_phi (ssa , var - ssa -> vars , phi );
178+ second_phi = zend_ssa_next_use_phi (ssa , var - ssa -> vars , second_phi );
179+ if (!second_phi ) {
180+ break ;
181+ }
182+ second_phi = zend_ssa_next_use_phi (ssa , var - ssa -> vars , second_phi );
183+ if (phi == second_phi ) {
165184 FAIL ("cycle in phi uses of " VARFMT "\n" , VAR (i ));
166185 goto finish ;
167186 }
187+ }
188+
189+ FOREACH_PHI_USE (var , phi ) {
168190 if (!is_in_phi_sources (ssa , phi , i )) {
169191 FAIL ("var " VARFMT " not in phi sources of %d\n" , VAR (i ), phi -> ssa_var );
170192 }
0 commit comments