mirror of
https://github.com/golang/go
synced 2024-11-23 05:40:04 -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:
parent
28c6648416
commit
b59dd94f33
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
57
test/fixedbugs/issue9017.go
Normal file
57
test/fixedbugs/issue9017.go
Normal 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"
|
||||
}
|
Loading…
Reference in New Issue
Block a user