]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/gc: method selector should not auto-deref named pointer type
authorChris Manghane <cmang@golang.org>
Tue, 9 Dec 2014 15:59:24 +0000 (07:59 -0800)
committerChris Manghane <cmang@golang.org>
Wed, 25 Feb 2015 19:27:30 +0000 (19:27 +0000)
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>

src/cmd/internal/gc/subr.go
src/cmd/internal/gc/typecheck.go
test/fixedbugs/issue9017.go [new file with mode: 0644]

index f7c075840015042d08ab993b81d70df4980fa96a..9dc573e79528cbb174d73499bfc91f5e14ebcc9b 100644 (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))
        }
 
index 9fa19300af8342acbffd96f92a97cd6a5b8a7081..1468d5fb45a0edd2539182bb65f7eff74ca08972 100644 (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
diff --git a/test/fixedbugs/issue9017.go b/test/fixedbugs/issue9017.go
new file mode 100644 (file)
index 0000000..e19bac2
--- /dev/null
@@ -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"
+}