mirror of
https://github.com/golang/go
synced 2024-11-26 17:46:57 -07:00
cmd/compile: fix method expressions with anonymous receivers
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>
This commit is contained in:
parent
84b784a84f
commit
950a56899a
@ -1474,6 +1474,7 @@ func itabsym(it *obj.LSym, offset int64) *obj.LSym {
|
|||||||
return syms[methodnum]
|
return syms[methodnum]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addsignat ensures that a runtime type descriptor is emitted for t.
|
||||||
func addsignat(t *types.Type) {
|
func addsignat(t *types.Type) {
|
||||||
signatset[t] = struct{}{}
|
signatset[t] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -2378,6 +2378,16 @@ func looktypedot(n *Node, t *types.Type, dostrcmp int) bool {
|
|||||||
return false
|
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.Sym = methodSym(t, n.Sym)
|
||||||
n.Xoffset = f2.Offset
|
n.Xoffset = f2.Offset
|
||||||
n.Type = f2.Type
|
n.Type = f2.Type
|
||||||
|
@ -45,10 +45,9 @@ func main() {
|
|||||||
interface{ m1(string) }.m1(x, "d")
|
interface{ m1(string) }.m1(x, "d")
|
||||||
want += " m1(d)"
|
want += " m1(d)"
|
||||||
|
|
||||||
// cannot link the call below - see #22444
|
g := struct{ T }.m2
|
||||||
// g := struct{ T }.m2
|
g(struct{ T }{})
|
||||||
// g(struct{T}{})
|
want += " m2()"
|
||||||
// want += " m2()"
|
|
||||||
|
|
||||||
if got != want {
|
if got != want {
|
||||||
panic("got" + got + ", want" + want)
|
panic("got" + got + ", want" + want)
|
||||||
|
Loading…
Reference in New Issue
Block a user