From 93fcb922570ac3b601f5addbe408866641783dac Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 20 Oct 2014 22:04:12 -0400 Subject: [PATCH] cmd/gc: disallow call of *T method using **T variable MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 7 +++++-- test/fixedbugs/bug371.go | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 2ad8ab5bff..714c662681 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -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); diff --git a/test/fixedbugs/bug371.go b/test/fixedbugs/bug371.go index 6329e9635a..86c73bf4a8 100644 --- a/test/fixedbugs/bug371.go +++ b/test/fixedbugs/bug371.go @@ -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" } -- 2.50.0