@@ -1951,6 +1951,28 @@ static void sccp_mark_feasible_successors(
19511951 scdf_mark_edge_feasible (scdf , block_num , block -> successors [s ]);
19521952}
19531953
1954+ /* Unlike zend_is_identical(), this does not treat 0.0 and -0.0 as the same value.
1955+ * Returns int to be usable as compare_func_t. */
1956+ static int sccp_values_differ (const void * p1 , const void * p2 )
1957+ {
1958+ const zval * a = p1 ;
1959+ const zval * b = p2 ;
1960+
1961+ if (Z_TYPE_P (a ) != Z_TYPE_P (b )) {
1962+ return 1 ;
1963+ }
1964+ if (Z_TYPE_P (a ) == IS_DOUBLE ) {
1965+ return memcmp (& Z_DVAL_P (a ), & Z_DVAL_P (b ), sizeof (double )) != 0 ;
1966+ }
1967+ if (Z_TYPE_P (a ) == IS_ARRAY ) {
1968+ return Z_ARRVAL_P (a ) != Z_ARRVAL_P (b )
1969+ && zend_hash_compare (Z_ARRVAL_P (a ), Z_ARRVAL_P (b ), sccp_values_differ , 1 ) != 0 ;
1970+ }
1971+ ZEND_ASSERT (IS_PARTIAL_ARRAY (a ) || IS_PARTIAL_OBJECT (a )
1972+ || ((1 << Z_TYPE_P (a )) & (MAY_BE_UNDEF |MAY_BE_NULL |MAY_BE_BOOL |MAY_BE_LONG |MAY_BE_STRING )));
1973+ return !zend_is_identical (a , b );
1974+ }
1975+
19541976static void join_hash_tables (HashTable * ret , const HashTable * ht1 , const HashTable * ht2 )
19551977{
19561978 zend_ulong index ;
@@ -1963,7 +1985,7 @@ static void join_hash_tables(HashTable *ret, const HashTable *ht1, const HashTab
19631985 } else {
19641986 val2 = zend_hash_index_find (ht2 , index );
19651987 }
1966- if (val2 && zend_is_identical (val1 , val2 )) {
1988+ if (val2 && ! sccp_values_differ (val1 , val2 )) {
19671989 if (key ) {
19681990 val1 = zend_hash_add_new (ret , key , val1 );
19691991 } else {
@@ -2031,7 +2053,7 @@ static void join_phi_values(zval *a, const zval *b, bool escape) {
20312053 zval_ptr_dtor_nogc (a );
20322054 MAKE_BOT (a );
20332055 }
2034- } else if (! zend_is_identical (a , b )) {
2056+ } else if (sccp_values_differ (a , b )) {
20352057 if (join_partial_arrays (a , b ) == FAILURE ) {
20362058 zval_ptr_dtor_nogc (a );
20372059 MAKE_BOT (a );
0 commit comments