]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: disallow call of *T method using **T variable
authorRuss Cox <rsc@golang.org>
Tue, 21 Oct 2014 02:04:12 +0000 (22:04 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 21 Oct 2014 02:04:12 +0000 (22:04 -0400)
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

src/cmd/gc/typecheck.c
test/fixedbugs/bug371.go

index 2ad8ab5bff1a981b3841b407188e5ddffc4879ef..714c662681e92b58adbd9249b6641ea42c5ca11e 100644 (file)
@@ -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);
index 6329e9635a2dadbaed3b2c59a475c7fcd4898c7e..86c73bf4a8f1be3e197c5b7ab9c1bc69de39b520 100644 (file)
@@ -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"
 }