]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: clean up encoding of method expressions and add test
authorRobert Griesemer <gri@golang.org>
Wed, 11 May 2016 18:28:36 +0000 (11:28 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 11 May 2016 19:23:04 +0000 (19:23 +0000)
Fixes #15646.

Change-Id: Ic13d1adc0a358149209195cdb03811eeee506fb8
Reviewed-on: https://go-review.googlesource.com/23052
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/bimport.go
test/fixedbugs/issue15646.dir/a.go [new file with mode: 0644]
test/fixedbugs/issue15646.dir/b.go [new file with mode: 0644]
test/fixedbugs/issue15646.go [new file with mode: 0644]

index cd2963e8e64e09ea146bd22e7855b2f5d0bfa1e6..3fe729618b4885660801bc03a8b9873abc5b5f7c 100644 (file)
@@ -1157,9 +1157,9 @@ func (p *exporter) expr(n *Node) {
                // Special case: name used as local variable in export.
                // _ becomes ~b%d internally; print as _ for export
                if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
-                       // case 0: mapped to ONAME
-                       p.op(ONAME)
-                       p.bool(true) // indicate blank identifier
+                       // case 0: mapped to OPACK
+                       p.op(OPACK)
+                       p.string("_") // inlined and customized version of p.sym(n)
                        break
                }
 
@@ -1174,22 +1174,18 @@ func (p *exporter) expr(n *Node) {
                // but for export, this should be rendered as (*pkg.T).meth.
                // These nodes have the special property that they are names with a left OTYPE and a right ONAME.
                if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
-                       // case 2: mapped to ONAME
-                       p.op(ONAME)
-                       // TODO(gri) can we map this case directly to OXDOT
-                       //           and then get rid of the bool here?
-                       p.bool(false) // indicate non-blank identifier
-                       p.typ(n.Left.Type)
+                       // case 2: mapped to OXDOT
+                       p.op(OXDOT)
+                       p.expr(n.Left) // n.Left.Op == OTYPE
                        p.fieldSym(n.Right.Sym, true)
                        break
                }
 
                // case 3: mapped to OPACK
-               p.op(OPACK)
-               p.sym(n) // fallthrough inlined here
+               fallthrough
 
        case OPACK, ONONAME:
-               p.op(op)
+               p.op(OPACK)
                p.sym(n)
 
        case OTYPE:
@@ -1508,6 +1504,8 @@ func (p *exporter) fieldSym(s *Sym, short bool) {
        }
 }
 
+// sym must encode the _ (blank) identifier as a single string "_" since
+// encoding for some nodes is based on this assumption (e.g. ONAME nodes).
 func (p *exporter) sym(n *Node) {
        s := n.Sym
        if s.Pkg != nil {
index cb375a0ac3fd5b8407875f683979d1d5fdaee200..c161c4ffb10c93c2993b7516ac7fc7ce007de24e 100644 (file)
@@ -798,15 +798,10 @@ func (p *importer) node() *Node {
                }
                return n
 
-       case ONAME:
-               if p.bool() {
-                       // "_"
-                       // TODO(gri) avoid repeated "_" lookup
-                       return mkname(Pkglookup("_", localpkg))
-               }
-               return NodSym(OXDOT, typenod(p.typ()), p.fieldSym())
+       // case ONAME, OPACK, ONONAME:
+       //      unreachable - mapped to case OPACK below by exporter
 
-       case OPACK, ONONAME:
+       case OPACK:
                return mkname(p.sym())
 
        case OTYPE:
diff --git a/test/fixedbugs/issue15646.dir/a.go b/test/fixedbugs/issue15646.dir/a.go
new file mode 100644 (file)
index 0000000..842f196
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+package a
+
+type T struct{}
+
+func (T) m() string {
+       return "m"
+}
+
+func (*T) mp() string {
+       return "mp"
+}
+
+func F() func(T) string {
+       return T.m // method expression
+}
+
+func Fp() func(*T) string {
+       return (*T).mp // method expression
+}
diff --git a/test/fixedbugs/issue15646.dir/b.go b/test/fixedbugs/issue15646.dir/b.go
new file mode 100644 (file)
index 0000000..3d011ba
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2016 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.
+
+package main
+
+import "./a" // import must succeed
+
+func main() {
+       if a.F()(a.T{}) != "m" {
+               panic(0)
+       }
+       if a.Fp()(nil) != "mp" {
+               panic(1)
+       }
+}
diff --git a/test/fixedbugs/issue15646.go b/test/fixedbugs/issue15646.go
new file mode 100644 (file)
index 0000000..cd4ba9d
--- /dev/null
@@ -0,0 +1,9 @@
+// rundir
+
+// Copyright 2016 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.
+
+// Test that method expressions are correctly encoded
+// in binary export data and can be imported again.
+package ignore
\ No newline at end of file