shithub: mc

Download patch

ref: c8166647a8f780ba1a21f3eb460d983c96048759
parent: 69ff322bc36cc9bbdc00528ef86031f631daf925
author: Ori Bernstein <[email protected]>
date: Mon Aug 19 13:43:41 EDT 2013

Hash the type parameters correctly when substituting.

    Code shifts lead to us hashing the wrong things, leading to bad
    substitutions. Fix this.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -208,7 +208,7 @@
         return t;
 
     tybind(st, t);
-    ht = mkht(strhash, streq);
+    ht = mkht(tyhash, streq);
     t = tyspecialize(t, ht);
     htfree(ht);
     tyunbind(st, t);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -305,6 +305,8 @@
 int ptreq(void *a, void *b);
 ulong inthash(uint64_t key);
 int inteq(uint64_t a, uint64_t b);
+ulong tyhash(void *t);
+int tyeq(void *a, void *b);
 
 /* util functions */
 void *zalloc(size_t size);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -344,42 +344,6 @@
     return name;
 }
 
-ulong tyhash(void *ty)
-{
-    size_t i;
-    Type *t;
-    ulong hash;
-
-    t = (Type *)ty;
-    if (t->type == Typaram)
-        hash = strhash(t->pname);
-    else
-        hash = inthash(t->tid);
-
-    for (i = 0; i < t->nparam; i++)
-        hash ^= tyhash(t->param[i]);
-    return hash;
-}
-
-int tyeq(void *t1, void *t2)
-{
-    Type *a, *b;
-    size_t i;
-
-    a = (Type *)t1;
-    b = (Type *)t2;
-    if (a->type == Typaram && b->type == Typaram)
-        return streq(a->pname, b->pname);
-    if (a->tid == b->tid)
-        return 1;
-    if (a->nparam != b->nparam)
-        return 0;
-    for (i = 0; i < a->nparam; i++)
-        if (!tyeq(a->param[i], b->param[i]))
-            return 0;
-    return 1;
-}
-
 /*
  * Takes a generic declaration, and creates a specialized
  * duplicate of it with type 'to'. It also generates
--- a/parse/type.c
+++ b/parse/type.c
@@ -520,6 +520,42 @@
     return strdup(buf);
 }
 
+ulong tyhash(void *ty)
+{
+    size_t i;
+    Type *t;
+    ulong hash;
+
+    t = (Type *)ty;
+    if (t->type == Typaram)
+        hash = strhash(t->pname);
+    else
+        hash = inthash(t->tid);
+
+    for (i = 0; i < t->nparam; i++)
+        hash ^= tyhash(t->param[i]);
+    return hash;
+}
+
+int tyeq(void *t1, void *t2)
+{
+    Type *a, *b;
+    size_t i;
+
+    a = (Type *)t1;
+    b = (Type *)t2;
+    if (a->type == Typaram && b->type == Typaram)
+        return streq(a->pname, b->pname);
+    if (a->tid == b->tid)
+        return 1;
+    if (a->nparam != b->nparam)
+        return 0;
+    for (i = 0; i < a->nparam; i++)
+        if (!tyeq(a->param[i], b->param[i]))
+            return 0;
+    return 1;
+}
+
 void tyinit(Stab *st)
 {
     int i;