shithub: mc

Download patch

ref: 01243d18cc0d8795a9887bc3565d5f48ce3c9430
parent: a537b8fe4a69dea9e3150b01785b18c5d4d3b374
author: Ori Bernstein <[email protected]>
date: Thu Dec 18 09:52:43 EST 2014

Fix up type equality/hashing.

    Now more things that should be equal will compare or
    hash as equal.

--- a/parse/type.c
+++ b/parse/type.c
@@ -633,10 +633,13 @@
     ulong hash;
 
     t = (Type *)ty;
-    if (t->type == Typaram)
-        hash = strhash(t->pname);
-    else
-        hash = inthash(t->tid);
+    switch (t->type) {
+        case Typaram:   hash = strhash(t->pname);       break;
+        case Tyvar:     hash = inthash(t->tid);         break;
+        case Tyunion:   hash = inthash(t->tid);         break;
+        case Tystruct:  hash = inthash(t->tid);         break;
+        default:        hash = inthash(t->type);        break;
+    }
 
     for (i = 0; i < t->narg; i++)
         hash ^= tyhash(t->arg[i]);
@@ -643,6 +646,22 @@
     return hash;
 }
 
+static int valeq(Node *a, Node *b)
+{
+    if (a == b)
+        return 1;
+
+    /* unwrap to Nlit */
+    if (exprop(a) == Olit)
+        a = a->expr.args[0];
+    if (exprop(b) == Olit)
+        b = b->expr.args[0];
+
+    if (a->type != Nlit || b->type != Nlit)
+        return 0;
+    return liteq(a, b);
+}
+
 int tyeq(void *t1, void *t2)
 {
     Type *a, *b;
@@ -652,6 +671,8 @@
     b = (Type *)t2;
     if (a == b)
         return 1;
+    if (!a || !b)
+        return 0;
     if (a->type != b->type)
         return 0;
     if (a->tid == b->tid)
@@ -666,11 +687,20 @@
         case Typaram:
             return streq(a->pname, b->pname);
             break;
+        case Tyvar:
+            if (a->tid != b->tid)
+                return 0;
+            break;
         case Tyunion:
             for (i = 0; i < a->nmemb; i++)
                 if (!tyeq(a->udecls[i]->etype, b->udecls[i]->etype))
                     return 0;
             break;
+        case Tystruct:
+            for (i = 0; i < a->nmemb; i++)
+                if (strcmp(declname(a->sdecls[i]), declname(b->sdecls[i])) != 0)
+                    return 0;
+            break;
         case Tyname:
             if (!nameeq(a->name, b->name))
                 return 0;
@@ -681,12 +711,16 @@
                 if (!tyeq(a->sub[i], b->sub[i]))
                     return 0;
             break;
+        case Tyarray:
+            if (!valeq(a->asize, b->asize))
+                return 0;
+            break;
         default:
-            for (i = 0; i < a->nsub; i++)
-                if (!tyeq(a->sub[i], b->sub[i]))
-                    return 0;
             break;
     }
+    for (i = 0; i < a->nsub; i++)
+        if (!tyeq(a->sub[i], b->sub[i]))
+            return 0;
     return 1;
 }