Commit b4f8e01a authored by Russ Cox's avatar Russ Cox

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
parent 638233a7
...@@ -466,6 +466,7 @@ dumpsignatures(void) ...@@ -466,6 +466,7 @@ dumpsignatures(void)
Addr at, ao, ac, ad; Addr at, ao, ac, ad;
Prog *p; Prog *p;
char *sp; char *sp;
char buf[NSYMB];
// copy externdcl list to signatlist // copy externdcl list to signatlist
for(d=externdcl; d!=D; d=d->forw) { for(d=externdcl; d!=D; d=d->forw) {
...@@ -583,7 +584,7 @@ dumpsignatures(void) ...@@ -583,7 +584,7 @@ dumpsignatures(void)
sp = strchr(s1->name, '_'); sp = strchr(s1->name, '_');
if(sp != nil) if(sp != nil)
a->name = sp+1; a->name = sp+1;
a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0); a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
a->perm = o; a->perm = o;
snprint(namebuf, sizeof(namebuf), "%s_%s", snprint(namebuf, sizeof(namebuf), "%s_%s",
...@@ -608,7 +609,9 @@ dumpsignatures(void) ...@@ -608,7 +609,9 @@ dumpsignatures(void)
p->to.offset = stringo; p->to.offset = stringo;
ot += widthptr; 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) { if(et == TINTER) {
// first field of an interface signature // first field of an interface signature
...@@ -733,6 +736,7 @@ dumpsignatures(void) ...@@ -733,6 +736,7 @@ dumpsignatures(void)
ot += widthptr; ot += widthptr;
} }
datastring(b->name, strlen(b->name)+1); datastring(b->name, strlen(b->name)+1);
} }
// nil field name at end // nil field name at end
......
...@@ -1406,6 +1406,10 @@ ismethod(Type *t) ...@@ -1406,6 +1406,10 @@ ismethod(Type *t)
if(t == T) if(t == T)
return T; return T;
// no interfaces
if(t->etype == TINTER || (t->etype == tptr && t->type->etype == TINTER))
return T;
a = algtype(t); a = algtype(t);
// direct receiver // direct receiver
......
...@@ -40,7 +40,7 @@ static Map* hash[1009]; ...@@ -40,7 +40,7 @@ static Map* hash[1009];
static void static void
printsigi(Sigi *si) printsigi(Sigi *si)
{ {
int32 i, n; int32 i;
byte *name; byte *name;
sys·printpointer(si); sys·printpointer(si);
...@@ -125,7 +125,7 @@ hashmap(Sigi *si, Sigt *st) ...@@ -125,7 +125,7 @@ hashmap(Sigi *si, Sigt *st)
m->sigi = si; m->sigi = si;
m->sigt = st; m->sigt = st;
nt = 0; nt = 1;
for(ni=1; (iname=si[ni].name) != nil; ni++) { // ni=1: skip first word for(ni=1; (iname=si[ni].name) != nil; ni++) { // ni=1: skip first word
// pick up next name from // pick up next name from
// interface signature // interface signature
...@@ -136,9 +136,14 @@ hashmap(Sigi *si, Sigt *st) ...@@ -136,9 +136,14 @@ hashmap(Sigi *si, Sigt *st)
// from structure signature // from structure signature
sname = st[nt].name; sname = st[nt].name;
if(sname == nil) { 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((int8*)iname);
prints(": "); prints("\n");
throw("hashmap: failed to find method"); throw("interface conversion");
m->bad = 1; m->bad = 1;
m->link = hash[h]; m->link = hash[h];
hash[h] = m; hash[h] = m;
......
...@@ -2,6 +2,20 @@ ...@@ -2,6 +2,20 @@
=========== ./helloworld.go =========== ./helloworld.go
hello, world hello, world
=========== ./interface1.go
./interface1.go:5: syntax error near package
./interface1.go:31: illegal types for operand: AS
interface { Next () (*Inst) }
*Inst
=========== ./interface2.go
cannot convert type S to interface I: missing method Foo
throw: interface conversion
SIGSEGV: segmentation violation
Faulting address: 0x0
pc: xxx
=========== ./peano.go =========== ./peano.go
0! = 1 0! = 1
1! = 1 1! = 1
...@@ -64,6 +78,7 @@ BUG: compilation should succeed ...@@ -64,6 +78,7 @@ BUG: compilation should succeed
=========== bugs/bug074.go =========== bugs/bug074.go
bugs/bug074.go:6: syntax error near string bugs/bug074.go:6: syntax error near string
bugs/bug074.go:6: syntax error near string
bugs/bug074.go:7: x: undefined bugs/bug074.go:7: x: undefined
BUG: compiler crashes - Bus error BUG: compiler crashes - Bus error
......
// errchk $G $D/$F.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package main
type Inst interface {
Next() *Inst;
}
type Regexp struct {
code *[]Inst;
start Inst;
}
type Start struct {
foo *Inst;
}
func (start *Start) Next() *Inst { return nil }
func AddInst(Inst) *Inst {
print("ok in addinst\n");
return nil
}
func main() {
re := new(Regexp);
print("call addinst\n");
var x Inst = AddInst(new(Start));
print("return from addinst\n");
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
type S struct
type I interface {
Foo()
}
func main() {
var s *S;
var i I;
i = s;
}
// hide S down here to avoid static warning
type S struct {
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment