]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: re-compile instantiated generic methods in linkshared mode
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 17 Mar 2023 17:53:07 +0000 (00:53 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 22 Mar 2023 04:04:11 +0000 (04:04 +0000)
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>

misc/cgo/testshared/shared_test.go
misc/cgo/testshared/testdata/issue58966/main.go [new file with mode: 0644]
src/cmd/compile/internal/noder/unified.go

index 0b589d023bb06ebc3476c11c06b254ca4e057ccd..e300e20e2008053b0cfc04aeff329e35252d9696 100644 (file)
@@ -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 (file)
index 0000000..2d923c3
--- /dev/null
@@ -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():
+       }
+}
index f1788c210e30afb0ea9478d04cc241250d3fde54..6c4ac66e3d0eac1be69ebeebd0ea0e458d2416a7 100644 (file)
@@ -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)