support testing/synctest when a non-test package imports "testing" too

As spotted by scripts/check-third-party.sh, it's possible to import
the testing package without using `go test`, so our previous solution
to only load testing/synctest when running `go test` was not enough.

Add a regression test via stdimporter in gogarble.txtar.
This commit is contained in:
Daniel Martí
2025-08-30 16:33:50 +01:00
parent 298a131506
commit 36fcc61c4e
4 changed files with 8 additions and 13 deletions

View File

@@ -87,8 +87,10 @@ var runtimeAndLinknamed = []string{
"unique", // go1.25 "unique", // go1.25
"weak", // go1.25 "weak", // go1.25
// The net package linknames to the runtime, not the other way around. // The net package linknames to the runtime, not the other way around.
// TODO: support this automatically via our script.
"net", "net",
// The testing package uses a //go:linkname directive pointing to testing/synctest,
// but it doesn't import the package, presumably to avoid an import cycle.
"testing/synctest",
} }
var compilerIntrinsics = map[string]map[string]bool{ var compilerIntrinsics = map[string]map[string]bool{

View File

@@ -53,8 +53,10 @@ var runtimeAndLinknamed = []string{
"{{ $path.String }}", // {{ $path.GoVersionLang }} "{{ $path.String }}", // {{ $path.GoVersionLang }}
{{- end }} {{- end }}
// The net package linknames to the runtime, not the other way around. // The net package linknames to the runtime, not the other way around.
// TODO: support this automatically via our script.
"net", "net",
// The testing package uses a //go:linkname directive pointing to testing/synctest,
// but it doesn't import the package, presumably to avoid an import cycle.
"testing/synctest",
} }
var compilerIntrinsics = map[string]map[string]bool{ var compilerIntrinsics = map[string]map[string]bool{

View File

@@ -279,23 +279,12 @@ func appendListedPackages(packages []string, mainBuild bool) error {
// Similar flags to what go/packages uses. // Similar flags to what go/packages uses.
"-json", "-export", "-compiled", "-e", "-json", "-export", "-compiled", "-e",
} }
if len(packages) == 0 {
// As we may append to the packages slice below,
// ensure that zero packages still means "the current directory".
packages = append(packages, ".")
}
if mainBuild { if mainBuild {
// When loading the top-level packages we are building, // When loading the top-level packages we are building,
// we want to transitively load all their dependencies as well. // we want to transitively load all their dependencies as well.
// That is not the case when loading standard library packages, // That is not the case when loading standard library packages,
// as runtimeAndLinknamed already contains transitive dependencies. // as runtimeAndLinknamed already contains transitive dependencies.
args = append(args, "-deps") args = append(args, "-deps")
if slices.Contains(sharedCache.ForwardBuildFlags, "-test") {
// The testing package uses a //go:linkname directive pointing to testing/synctest,
// but it doesn't import the package, presumably to avoid an import cycle.
// For the linkname to obfuscate correctly, we need to list both when using `go test`.
packages = append(packages, "testing/synctest")
}
} }
args = append(args, garbleBuildFlags...) args = append(args, garbleBuildFlags...)
args = append(args, sharedCache.ForwardBuildFlags...) args = append(args, sharedCache.ForwardBuildFlags...)

View File

@@ -91,6 +91,7 @@ import (
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"syscall" "syscall"
"testing"
"time" "time"
) )
@@ -107,6 +108,7 @@ func main() {
debug.WriteHeapDump(1) debug.WriteHeapDump(1)
time.Now() time.Now()
syscall.Listen(0, 1) syscall.Listen(0, 1)
testing.MainStart(nil, nil, nil, nil, nil)
} }
} }