mirror of
https://github.com/golang/go
synced 2024-11-11 22:20:22 -07:00
cmd/gc: disallow call of *T method using **T variable
This brings cmd/gc in line with the spec on this question. It might break existing code, but that code was not conformant with the spec. Credit to Rémy for finding the broken code. Fixes #6366. LGTM=r R=golang-codereviews, r CC=adonovan, golang-codereviews, gri https://golang.org/cl/129550043
This commit is contained in:
parent
70f2f1b470
commit
93fcb92257
@ -2127,13 +2127,16 @@ lookdot(Node *n, Type *t, int dostrcmp)
|
||||
n->left = nod(OADDR, n->left, N);
|
||||
n->left->implicit = 1;
|
||||
typecheck(&n->left, Etype|Erv);
|
||||
} else if(tt->etype == tptr && eqtype(tt->type, rcvr)) {
|
||||
} else if(tt->etype == tptr && rcvr->etype != tptr && eqtype(tt->type, rcvr)) {
|
||||
n->left = nod(OIND, n->left, N);
|
||||
n->left->implicit = 1;
|
||||
typecheck(&n->left, Etype|Erv);
|
||||
} else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), rcvr)) {
|
||||
} else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), derefall(rcvr))) {
|
||||
yyerror("calling method %N with receiver %lN requires explicit dereference", n->right, n->left);
|
||||
while(tt->etype == tptr) {
|
||||
// Stop one level early for method with pointer receiver.
|
||||
if(rcvr->etype == tptr && tt->type->etype != tptr)
|
||||
break;
|
||||
n->left = nod(OIND, n->left, N);
|
||||
n->left->implicit = 1;
|
||||
typecheck(&n->left, Etype|Erv);
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
package main
|
||||
|
||||
type T struct {}
|
||||
type T struct{}
|
||||
|
||||
func (t *T) pm() {}
|
||||
func (t T) m() {}
|
||||
func (t T) m() {}
|
||||
|
||||
func main() {
|
||||
p := &T{}
|
||||
@ -20,5 +20,5 @@ func main() {
|
||||
|
||||
q := &p
|
||||
q.m() // ERROR "requires explicit dereference"
|
||||
q.pm()
|
||||
q.pm() // ERROR "requires explicit dereference"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user