From a1cedf08428bdb91916bb5317c8413212308048c Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Fri, 31 Mar 2017 07:14:16 -0400 Subject: [PATCH] cmd/link: canonicalize the "package" of dupok text symbols Dupok symbols may be defined in multiple packages. Its associated package is chosen sort of arbitrarily (the first containing package that the linker loads). Canonicalize its package to the package with which it will be laid down in text, which is the first package in dependency order that defines the symbol. So later passes (for example, trampoline insertion pass) know that the dupok symbol is laid down along with the package. Fixes #19764. Change-Id: I7cbc7474ff3016d5069c8b7be04af934abab8bc3 Reviewed-on: https://go-review.googlesource.com/39150 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Lynn Boger Reviewed-by: David Chase --- src/cmd/link/internal/ld/lib.go | 6 ++++++ test/fixedbugs/issue19764.dir/a.go | 15 +++++++++++++++ test/fixedbugs/issue19764.dir/b.go | 13 +++++++++++++ test/fixedbugs/issue19764.go | 10 ++++++++++ 4 files changed, 44 insertions(+) create mode 100644 test/fixedbugs/issue19764.dir/a.go create mode 100644 test/fixedbugs/issue19764.dir/b.go create mode 100644 test/fixedbugs/issue19764.go diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index a5c72cf8b2d..d13c93b9a13 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -647,6 +647,12 @@ func (ctxt *Link) loadlib() { if !s.Attr.OnList() { ctxt.Textp = append(ctxt.Textp, s) s.Attr |= AttrOnList + // dupok symbols may be defined in multiple packages. its + // associated package is chosen sort of arbitrarily (the + // first containing package that the linker loads). canonicalize + // it here to the package with which it will be laid down + // in text. + s.File = pathtoprefix(lib.Pkg) } } } diff --git a/test/fixedbugs/issue19764.dir/a.go b/test/fixedbugs/issue19764.dir/a.go new file mode 100644 index 00000000000..64538e5bdf0 --- /dev/null +++ b/test/fixedbugs/issue19764.dir/a.go @@ -0,0 +1,15 @@ +// Copyright 2017 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{ _ int } +func (t T) M() {} + +type I interface { M() } + +func F() { + var t I = &T{} + t.M() // call to the wrapper (*T).M +} diff --git a/test/fixedbugs/issue19764.dir/b.go b/test/fixedbugs/issue19764.dir/b.go new file mode 100644 index 00000000000..d39f125f37c --- /dev/null +++ b/test/fixedbugs/issue19764.dir/b.go @@ -0,0 +1,13 @@ +// Copyright 2017 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" + +func main() { + var x a.I = &a.T{} + x.M() // call to the wrapper (*T).M + a.F() // make sure a.F is not dead, which also calls (*T).M inside package a +} diff --git a/test/fixedbugs/issue19764.go b/test/fixedbugs/issue19764.go new file mode 100644 index 00000000000..26fb00be2d0 --- /dev/null +++ b/test/fixedbugs/issue19764.go @@ -0,0 +1,10 @@ +// rundir + +// Copyright 2017 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 19764: test that the linker's trampoline insertion +// pass is happy with direct calls to interface wrappers that +// may be defined in multiple packages. +package ignore