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)
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) {
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -2,6 +2,20 @@
=========== ./helloworld.go
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
0! = 1
1! = 1
......@@ -64,6 +78,7 @@ BUG: compilation should succeed
=========== bugs/bug074.go
bugs/bug074.go:6: syntax error near string
bugs/bug074.go:6: syntax error near string
bugs/bug074.go:7: x: undefined
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