diff options
| author | Russ Cox <rsc@golang.org> | 2008-10-08 09:21:57 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2008-10-08 09:21:57 -0700 |
| commit | b4f8e01acb8239eb8d31017d5f137cbda57e62d3 (patch) | |
| tree | ba4db825dc2016fbeb114668b1447487be5fdbaf /src | |
| parent | 638233a7d67d527c4f3e9465a18357264f1571ae (diff) | |
| download | go-b4f8e01acb8239eb8d31017d5f137cbda57e62d3.tar.xz | |
more interface checks:
- pointer to interface cannot have methods
- record type names for better runtime error
R=r,ken
DELTA=85 (80 added, 0 deleted, 5 changed)
OCL=16658
CL=16722
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/6g/obj.c | 8 | ||||
| -rw-r--r-- | src/cmd/gc/subr.c | 4 | ||||
| -rw-r--r-- | src/runtime/iface.c | 13 |
3 files changed, 19 insertions, 6 deletions
diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c index 28eb6b1c51..b4f44bbc3f 100644 --- a/src/cmd/6g/obj.c +++ b/src/cmd/6g/obj.c @@ -466,6 +466,7 @@ dumpsignatures(void) Addr at, ao, ac, ad; Prog *p; char *sp; + char buf[NSYMB]; // copy externdcl list to signatlist for(d=externdcl; d!=D; d=d->forw) { @@ -583,7 +584,7 @@ dumpsignatures(void) sp = strchr(s1->name, '_'); if(sp != nil) a->name = sp+1; - + a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0); a->perm = o; snprint(namebuf, sizeof(namebuf), "%s_%s", @@ -608,7 +609,9 @@ dumpsignatures(void) p->to.offset = stringo; ot += widthptr; - datastring("", 1); + // save type name for runtime error message + snprint(buf, sizeof buf, "%T", t); + datastring(buf, strlen(buf)+1); if(et == TINTER) { // first field of an interface signature @@ -733,6 +736,7 @@ dumpsignatures(void) ot += widthptr; } datastring(b->name, strlen(b->name)+1); + } // nil field name at end diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index c15039e36f..ddce14e6f3 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -1406,6 +1406,10 @@ ismethod(Type *t) if(t == T) return T; + // no interfaces + if(t->etype == TINTER || (t->etype == tptr && t->type->etype == TINTER)) + return T; + a = algtype(t); // direct receiver diff --git a/src/runtime/iface.c b/src/runtime/iface.c index e8c4cd6939..089975b923 100644 --- a/src/runtime/iface.c +++ b/src/runtime/iface.c @@ -40,7 +40,7 @@ static Map* hash[1009]; static void printsigi(Sigi *si) { - int32 i, n; + int32 i; byte *name; sys·printpointer(si); @@ -125,7 +125,7 @@ hashmap(Sigi *si, Sigt *st) m->sigi = si; m->sigt = st; - nt = 0; + nt = 1; for(ni=1; (iname=si[ni].name) != nil; ni++) { // ni=1: skip first word // pick up next name from // interface signature @@ -136,9 +136,14 @@ hashmap(Sigi *si, Sigt *st) // from structure signature sname = st[nt].name; if(sname == nil) { + prints("cannot convert type "); + prints((int8*)st[0].name); + prints(" to interface "); + prints((int8*)si[0].name); + prints(": missing method "); prints((int8*)iname); - prints(": "); - throw("hashmap: failed to find method"); + prints("\n"); + throw("interface conversion"); m->bad = 1; m->link = hash[h]; hash[h] = m; |
