]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix method expressions with anonymous receivers
authorMatthew Dempsky <mdempsky@google.com>
Fri, 6 Apr 2018 05:42:16 +0000 (22:42 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 6 Apr 2018 15:39:11 +0000 (15:39 +0000)
Method expressions with anonymous receiver types like "struct { T }.m"
require wrapper functions, which we weren't always creating. This in
turn resulted in linker errors.

This CL ensures that we generate wrapper functions for any anonymous
receiver types used in a method expression.

Fixes #22444.

Change-Id: Ia8ac27f238c2898965e57b82a91d959792d2ddd4
Reviewed-on: https://go-review.googlesource.com/105044
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/reflect.go
src/cmd/compile/internal/gc/typecheck.go
test/method7.go

index bd837b140eedb338ed4c22dab7fc192cefce2b47..053e3cb031c571dcabc6494143761dbd8492ce48 100644 (file)
@@ -1474,6 +1474,7 @@ func itabsym(it *obj.LSym, offset int64) *obj.LSym {
        return syms[methodnum]
 }
 
+// addsignat ensures that a runtime type descriptor is emitted for t.
 func addsignat(t *types.Type) {
        signatset[t] = struct{}{}
 }
index ea6c4c8dff283226213abb9f6d48e569a8f4ac4c..4254d5655d705c038597738573c5f0629d225568 100644 (file)
@@ -2378,6 +2378,16 @@ func looktypedot(n *Node, t *types.Type, dostrcmp int) bool {
                return false
        }
 
+       // The method expression T.m requires a wrapper when T is
+       // different from m's declared receiver type. We normally
+       // generate these wrappers while writing out runtime type
+       // descriptors, which is always done for types declared at
+       // package scope. However, we need to make sure to generate
+       // wrappers for anonymous receiver types too.
+       if mt.Sym == nil {
+               addsignat(t)
+       }
+
        n.Sym = methodSym(t, n.Sym)
        n.Xoffset = f2.Offset
        n.Type = f2.Type
index 72c88b377d55a6930f6834adb99c4937c1660773..15e123e85fa71dac6a63e22c72986aafe2ea71d8 100644 (file)
@@ -45,10 +45,9 @@ func main() {
        interface{ m1(string) }.m1(x, "d")
        want += " m1(d)"
 
-       // cannot link the call below - see #22444
-       // g := struct{ T }.m2
-       // g(struct{T}{})
-       // want += " m2()"
+       g := struct{ T }.m2
+       g(struct{ T }{})
+       want += " m2()"
 
        if got != want {
                panic("got" + got + ", want" + want)