mirror of
https://github.com/golang/go
synced 2024-11-24 23:07:56 -07:00
gc: bug fixes.
* better error for lookup of unexported field * do not assign "ideal string" type to typed string literal * do not confuse methods and fields during interface check Fixes #410. Fixes #411. Fixes #426. R=ken2 https://golang.org/cl/179069
This commit is contained in:
parent
101f499fa5
commit
5d754bfaea
@ -320,7 +320,7 @@ Sym*
|
||||
restrictlookup(char *name, char *pkg)
|
||||
{
|
||||
if(!exportname(name) && strcmp(pkg, package) != 0)
|
||||
yyerror("cannot refer to %s.%s", pkg, name);
|
||||
yyerror("cannot refer to unexported name %s.%s", pkg, name);
|
||||
return pkglookup(name, pkg);
|
||||
}
|
||||
|
||||
@ -2871,6 +2871,10 @@ ifacelookdot(Sym *s, Type *t, int *followptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(m->type->etype != TFUNC || m->type->thistuple == 0) {
|
||||
yyerror("%T.%S is a field, not a method", t, s);
|
||||
return T;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
static void implicitstar(Node**);
|
||||
static int onearg(Node*);
|
||||
static int lookdot(Node*, Type*);
|
||||
static int lookdot(Node*, Type*, int);
|
||||
static void typecheckaste(int, Type*, NodeList*, char*);
|
||||
static int exportassignok(Type*, char*);
|
||||
static Type* lookdot1(Sym *s, Type *t, Type *f);
|
||||
static Type* lookdot1(Sym *s, Type *t, Type *f, int);
|
||||
static int nokeys(NodeList*);
|
||||
static void typecheckcomplit(Node**);
|
||||
static void addrescapes(Node*);
|
||||
@ -102,7 +102,7 @@ reswitch:
|
||||
*/
|
||||
case OLITERAL:
|
||||
ok |= Erv;
|
||||
if(n->val.ctype == CTSTR)
|
||||
if(n->type == T && n->val.ctype == CTSTR)
|
||||
n->type = idealstring;
|
||||
goto ret;
|
||||
|
||||
@ -459,7 +459,10 @@ reswitch:
|
||||
n->op = ODOTPTR;
|
||||
checkwidth(t);
|
||||
}
|
||||
if(!lookdot(n, t)) {
|
||||
if(!lookdot(n, t, 0)) {
|
||||
if(lookdot(n, t, 1))
|
||||
yyerror("%#N undefined (cannot refer to unexported field %S)", n, n->right->sym);
|
||||
else
|
||||
yyerror("%#N undefined (type %T has no field %S)", n, t, n->right->sym);
|
||||
goto error;
|
||||
}
|
||||
@ -1168,12 +1171,14 @@ onearg(Node *n)
|
||||
}
|
||||
|
||||
static Type*
|
||||
lookdot1(Sym *s, Type *t, Type *f)
|
||||
lookdot1(Sym *s, Type *t, Type *f, int dostrcmp)
|
||||
{
|
||||
Type *r;
|
||||
|
||||
r = T;
|
||||
for(; f!=T; f=f->down) {
|
||||
if(dostrcmp && strcmp(f->sym->name, s->name) == 0)
|
||||
return f;
|
||||
if(f->sym != s)
|
||||
continue;
|
||||
if(r != T) {
|
||||
@ -1186,7 +1191,7 @@ lookdot1(Sym *s, Type *t, Type *f)
|
||||
}
|
||||
|
||||
static int
|
||||
lookdot(Node *n, Type *t)
|
||||
lookdot(Node *n, Type *t, int dostrcmp)
|
||||
{
|
||||
Type *f1, *f2, *tt, *rcvr;
|
||||
Sym *s;
|
||||
@ -1196,11 +1201,11 @@ lookdot(Node *n, Type *t)
|
||||
dowidth(t);
|
||||
f1 = T;
|
||||
if(t->etype == TSTRUCT || t->etype == TINTER)
|
||||
f1 = lookdot1(s, t, t->type);
|
||||
f1 = lookdot1(s, t, t->type, dostrcmp);
|
||||
|
||||
f2 = methtype(n->left->type);
|
||||
if(f2 != T)
|
||||
f2 = lookdot1(s, f2, f2->method);
|
||||
f2 = lookdot1(s, f2, f2->method, dostrcmp);
|
||||
|
||||
if(f1 != T) {
|
||||
if(f2 != T)
|
||||
@ -1793,7 +1798,7 @@ typecheckcomplit(Node **np)
|
||||
}
|
||||
l->left = newname(s);
|
||||
l->left->typecheck = 1;
|
||||
f = lookdot1(s, t, t->type);
|
||||
f = lookdot1(s, t, t->type, 0);
|
||||
typecheck(&l->right, Erv);
|
||||
if(f == nil) {
|
||||
yyerror("unknown %T field '%s' in struct literal", t, s->name);
|
||||
|
20
test/fixedbugs/bug229.go
Normal file
20
test/fixedbugs/bug229.go
Normal file
@ -0,0 +1,20 @@
|
||||
// errchk $G -e $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
|
||||
|
||||
import "testing"
|
||||
|
||||
func main() {
|
||||
var t testing.T
|
||||
|
||||
// make sure error mentions that
|
||||
// ch is unexported, not just "ch not found".
|
||||
|
||||
t.ch = nil // ERROR "unexported"
|
||||
|
||||
println(testing.anyLowercaseName("asdf")) // ERROR "unexported"
|
||||
}
|
25
test/fixedbugs/bug230.go
Normal file
25
test/fixedbugs/bug230.go
Normal file
@ -0,0 +1,25 @@
|
||||
// $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 string
|
||||
type I int
|
||||
type F float
|
||||
|
||||
func (S) m() {}
|
||||
func (I) m() {}
|
||||
func (F) m() {}
|
||||
|
||||
func main() {
|
||||
c := make(chan interface { m() }, 10)
|
||||
c <- I(0)
|
||||
c <- F(1)
|
||||
c <- S("hi")
|
||||
<-c
|
||||
<-c
|
||||
<-c
|
||||
}
|
22
test/fixedbugs/bug231.go
Normal file
22
test/fixedbugs/bug231.go
Normal file
@ -0,0 +1,22 @@
|
||||
// errchk $G -e $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
|
||||
|
||||
type I interface { m() }
|
||||
type T struct { m func() }
|
||||
type M struct {}
|
||||
func (M) m() {}
|
||||
|
||||
func main() {
|
||||
var t T
|
||||
var m M
|
||||
var i I
|
||||
|
||||
i = m
|
||||
i = t // ERROR "not a method"
|
||||
_ = i
|
||||
}
|
Loading…
Reference in New Issue
Block a user