| From 7a3bb16b43efba73674629eae4369f9004e37f22 Mon Sep 17 00:00:00 2001 |
| From: Cuong Manh Le <cuong.manhle.vn@gmail.com> |
| Date: Sat, 18 Mar 2023 00:53:07 +0700 |
| Subject: [PATCH] cmd/compile: re-compile instantiated generic methods in |
| linkshared mode |
| |
| For G[T] that was seen and compiled in imported package, it is not added |
| to typecheck.Target.Decls, prevent wasting compile time re-creating |
| DUPOKS symbols. However, the linker do not support a type symbol |
| referencing a method symbol across DSO boundary. That causes unreachable |
| sym error when building under -linkshared mode. |
| |
| To fix it, always re-compile generic methods in linkshared mode. |
| |
| Fixes #58966 |
| |
| Change-Id: I894b417cfe8234ae1fe809cc975889345df22cef |
| Reviewed-on: https://go-review.googlesource.com/c/go/+/477375 |
| Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> |
| Reviewed-by: Cherry Mui <cherryyz@google.com> |
| Reviewed-by: Matthew Dempsky <mdempsky@google.com> |
| TryBot-Result: Gopher Robot <gobot@golang.org> |
| |
| Upstream-Status: Backport [https://github.com/golang/go/commit/bcd82125f85c7c552493e863fa1bb14e6c444557] |
| |
| Signed-off-by: Jose Quaresma <jose.quaresma@foundries.io> |
| --- |
| misc/cgo/testshared/shared_test.go | 7 ++++++- |
| misc/cgo/testshared/testdata/issue58966/main.go | 15 +++++++++++++++ |
| src/cmd/compile/internal/noder/unified.go | 6 +++++- |
| 3 files changed, 26 insertions(+), 2 deletions(-) |
| create mode 100644 misc/cgo/testshared/testdata/issue58966/main.go |
| |
| diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go |
| index b14fb1cb3a..03da8f9435 100644 |
| --- a/misc/cgo/testshared/shared_test.go |
| +++ b/misc/cgo/testshared/shared_test.go |
| @@ -1112,8 +1112,13 @@ func TestStd(t *testing.T) { |
| t.Skip("skip in short mode") |
| } |
| t.Parallel() |
| + tmpDir := t.TempDir() |
| // Use a temporary pkgdir to not interfere with other tests, and not write to GOROOT. |
| // Cannot use goCmd as it runs with cloned GOROOT which is incomplete. |
| runWithEnv(t, "building std", []string{"GOROOT=" + oldGOROOT}, |
| - filepath.Join(oldGOROOT, "bin", "go"), "install", "-buildmode=shared", "-pkgdir="+t.TempDir(), "std") |
| + filepath.Join(oldGOROOT, "bin", "go"), "install", "-buildmode=shared", "-pkgdir="+tmpDir, "std") |
| + |
| + // Issue #58966. |
| + runWithEnv(t, "testing issue #58966", []string{"GOROOT=" + oldGOROOT}, |
| + filepath.Join(oldGOROOT, "bin", "go"), "run", "-linkshared", "-pkgdir="+tmpDir, "./issue58966/main.go") |
| } |
| diff --git a/misc/cgo/testshared/testdata/issue58966/main.go b/misc/cgo/testshared/testdata/issue58966/main.go |
| new file mode 100644 |
| index 0000000000..2d923c3607 |
| --- /dev/null |
| +++ b/misc/cgo/testshared/testdata/issue58966/main.go |
| @@ -0,0 +1,15 @@ |
| +// Copyright 2023 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 "crypto/elliptic" |
| + |
| +var curve elliptic.Curve |
| + |
| +func main() { |
| + switch curve { |
| + case elliptic.P224(): |
| + } |
| +} |
| diff --git a/src/cmd/compile/internal/noder/unified.go b/src/cmd/compile/internal/noder/unified.go |
| index ed97a09302..25136e6aad 100644 |
| --- a/src/cmd/compile/internal/noder/unified.go |
| +++ b/src/cmd/compile/internal/noder/unified.go |
| @@ -158,7 +158,11 @@ func readBodies(target *ir.Package, duringInlining bool) { |
| // Instantiated generic function: add to Decls for typechecking |
| // and compilation. |
| if fn.OClosure == nil && len(pri.dict.targs) != 0 { |
| - if duringInlining { |
| + // cmd/link does not support a type symbol referencing a method symbol |
| + // across DSO boundary, so force re-compiling methods on a generic type |
| + // even it was seen from imported package in linkshared mode, see #58966. |
| + canSkipNonGenericMethod := !(base.Ctxt.Flag_linkshared && ir.IsMethod(fn)) |
| + if duringInlining && canSkipNonGenericMethod { |
| inlDecls = append(inlDecls, fn) |
| } else { |
| target.Decls = append(target.Decls, fn) |