mirror of
https://github.com/golang/go
synced 2024-10-04 15:09:59 +00:00
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
This commit is contained in:
parent
638233a7d6
commit
b4f8e01acb
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
37
test/interface1.go
Normal file
37
test/interface1.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// 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");
|
||||
}
|
23
test/interface2.go
Normal file
23
test/interface2.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
// $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 {
|
||||
}
|
Loading…
Reference in a new issue