1
0
mirror of https://github.com/golang/go synced 2024-11-23 02:10:03 -07:00

cmd/internal/gc: method selector should not auto-deref named pointer type

Fixes #9017.

Change-Id: I26cb1e7d6e137ff145773169cfe2d8bd4e1b339c
Reviewed-on: https://go-review.googlesource.com/1252
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Chris Manghane <cmang@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Chris Manghane 2014-12-09 07:59:24 -08:00
parent 28c6648416
commit b59dd94f33
3 changed files with 73 additions and 0 deletions

View File

@ -2172,6 +2172,9 @@ out:
// rebuild elided dots
for c := d - 1; c >= 0; c-- {
if n.Left.Type != nil && Isptr[n.Left.Type.Etype] != 0 {
n.Left.Implicit = 1
}
n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym))
}

View File

@ -2433,6 +2433,19 @@ func lookdot(n *Node, t *Type, dostrcmp int) bool {
}
}
ll := n.Left
for ll.Left != nil {
ll = ll.Left
}
if ll.Implicit != 0 {
if Isptr[ll.Type.Etype] != 0 && ll.Type.Sym != nil && ll.Type.Sym.Def != nil && ll.Type.Sym.Def.Op == OTYPE {
// It is invalid to automatically dereference a named pointer type when selecting a method.
// Make n->left == ll to clarify error message.
n.Left = ll
return false
}
}
n.Right = methodname(n.Right, n.Left.Type)
n.Xoffset = f2.Width
n.Type = f2.Type

View File

@ -0,0 +1,57 @@
// errorcheck
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 9017: Method selector shouldn't automatically dereference a named pointer type.
package main
type T struct{ x int }
func (T) mT() {}
type S struct {
T
}
func (S) mS() {}
type P *S
type I interface {
mT()
}
func main() {
var s S
s.T.mT()
s.mT() // == s.T.mT()
var i I
_ = i
i = s.T
i = s
var ps = &s
ps.mS()
ps.T.mT()
ps.mT() // == ps.T.mT()
i = ps.T
i = ps
var p P = ps
(*p).mS()
p.mS() // ERROR "undefined"
i = *p
i = p // ERROR "cannot use|incompatible types"
p.T.mT()
p.mT() // ERROR "undefined"
i = p.T
i = p // ERROR "cannot use|incompatible types"
}