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;