Commit 93fcb922 authored by Russ Cox's avatar Russ Cox

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
parent 70f2f1b4
......@@ -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"
}
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