diff options
author | Russ Cox <rsc@golang.org> | 2014-10-20 22:04:12 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-10-20 22:04:12 -0400 |
commit | 2043f3b47093bc0258c14f13200a29042cf137e9 (patch) | |
tree | b1e018f69d50ff42907b2d21f28c4c0cb2e214f7 /src/cmd/gc | |
parent | e9ab7303f127c32b2021fa360e710e8e091d62c3 (diff) | |
download | go-2043f3b47093bc0258c14f13200a29042cf137e9.tar.gz |
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 issue 6366.
LGTM=r
R=golang-codereviews, r
CC=adonovan, golang-codereviews, gri
https://codereview.appspot.com/129550043
Diffstat (limited to 'src/cmd/gc')
-rw-r--r-- | src/cmd/gc/typecheck.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 2ad8ab5bf..714c66268 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); |