cmd/go: do not panic when computing Shlib for a package with no Target

In module mode, a non-main package lacks an install target.

The location of the .shlib corresponding to a given target is stored
in a .shlibname file alongside its install target, so in module mode
a non-main package also lacks a .shlibname file.

This also implies that such a package cannot be installed with
'go install -buildmode=linkshared', but that is a problem
for another day.

Fixes #35759
Updates #34347

Change-Id: Id3e0e068266d5fb9b061a59e70f9a65985d4973b
Reviewed-on: https://go-review.googlesource.com/c/go/+/208233
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 8fc33e3..0d63187 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -1584,7 +1584,10 @@
 		p.Target = ""
 	} else {
 		p.Target = p.Internal.Build.PkgObj
-		if cfg.BuildLinkshared {
+		if cfg.BuildLinkshared && p.Target != "" {
+			// TODO(bcmills): The reliance on p.Target implies that -linkshared does
+			// not work for any package that lacks a Target — such as a non-main
+			// package in module mode. We should probably fix that.
 			shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
 			shlib, err := ioutil.ReadFile(shlibnamefile)
 			if err != nil && !os.IsNotExist(err) {
diff --git a/src/cmd/go/testdata/script/list_linkshared.txt b/src/cmd/go/testdata/script/list_linkshared.txt
new file mode 100644
index 0000000..baae1e2
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_linkshared.txt
@@ -0,0 +1,16 @@
+env GO111MODULE=on
+
+# golang.org/issue/35759: 'go list -linkshared'
+# panicked if invoked on a test-only package.
+
+[!buildmode:shared] skip
+
+go list -f '{{.ImportPath}}: {{.Target}} {{.Shlib}}' -linkshared .
+stdout '^example.com:  $'
+
+-- go.mod --
+module example.com
+
+go 1.14
+-- x.go --
+package x