diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index 48b9e81e2da..6850fde2be6 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -41,9 +41,6 @@ func init() { BuildToolchainLinker = func() string { return "missing-linker" } } -// The test coverage mode affects package loading. Sigh. -var TestCoverMode string // -covermode flag - // An EnvVar is an environment variable Name=Value. type EnvVar struct { Name string diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index bf91bb74ada..1609459ef8e 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -959,10 +959,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) *Package if p.Name == "main" && cfg.Goarch == "arm" { ImportPaths = append(ImportPaths, "math") } - // In coverage atomic mode everything depends on sync/atomic. - if cfg.TestCoverMode == "atomic" && (!p.Standard || (p.ImportPath != "runtime/cgo" && p.ImportPath != "runtime/race" && p.ImportPath != "sync/atomic")) { - ImportPaths = append(ImportPaths, "sync/atomic") - } } // Runtime and its internal packages depend on runtime/internal/sys, diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go index a3f95b1548f..961466c2ff7 100644 --- a/src/cmd/go/internal/test/test.go +++ b/src/cmd/go/internal/test/test.go @@ -388,9 +388,9 @@ See the documentation of the testing package for more information. } var ( - testC bool // -c flag - testCover bool // -cover flag - // Note: testCoverMode is cfg.TestCoverMode (-covermode) + testC bool // -c flag + testCover bool // -cover flag + testCoverMode string // -covermode flag testCoverPaths []string // -coverpkg flag testCoverPkgs []*load.Package // -coverpkg flag testO string // -o flag @@ -548,7 +548,7 @@ func runTest(cmd *base.Command, args []string) { p.Stale = true // rebuild p.StaleReason = "rebuild for coverage" p.Internal.Fake = true // do not warn about rebuild - p.Internal.CoverMode = cfg.TestCoverMode + p.Internal.CoverMode = testCoverMode var coverFiles []string coverFiles = append(coverFiles, p.GoFiles...) coverFiles = append(coverFiles, p.CgoFiles...) @@ -559,6 +559,11 @@ func runTest(cmd *base.Command, args []string) { // Prepare build + run + print actions for all packages being tested. for _, p := range pkgs { + // sync/atomic import is inserted by the cover tool. See #18486 + if testCover && testCoverMode == "atomic" { + ensureImport(p, "sync/atomic") + } + buildTest, runTest, printTest, err := builderTest(&b, p) if err != nil { str := err.Error() @@ -650,6 +655,23 @@ func runTest(cmd *base.Command, args []string) { b.Do(root) } +// ensures that package p imports the named package +func ensureImport(p *load.Package, pkg string) { + for _, d := range p.Internal.Deps { + if d.Name == pkg { + return + } + } + + a := load.LoadPackage(pkg, &load.ImportStack{}) + if a.Error != nil { + base.Fatalf("load %s: %v", pkg, a.Error) + } + load.ComputeStale(a) + + p.Internal.Imports = append(p.Internal.Imports, a) +} + var windowsBadWords = []string{ "install", "patch", @@ -788,7 +810,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin ptest.Internal.Build.ImportPos = m if localCover { - ptest.Internal.CoverMode = cfg.TestCoverMode + ptest.Internal.CoverMode = testCoverMode var coverFiles []string coverFiles = append(coverFiles, ptest.GoFiles...) coverFiles = append(coverFiles, ptest.CgoFiles...) @@ -1361,7 +1383,7 @@ type testFuncs struct { } func (t *testFuncs) CoverMode() string { - return cfg.TestCoverMode + return testCoverMode } func (t *testFuncs) CoverEnabled() bool { diff --git a/src/cmd/go/internal/test/testflag.go b/src/cmd/go/internal/test/testflag.go index 1c44af5a005..a89afb312e7 100644 --- a/src/cmd/go/internal/test/testflag.go +++ b/src/cmd/go/internal/test/testflag.go @@ -174,7 +174,7 @@ func testFlags(args []string) (packageNames, passToTest []string) { case "covermode": switch value { case "set", "count", "atomic": - cfg.TestCoverMode = value + testCoverMode = value default: base.Fatalf("invalid flag argument for -covermode: %q", value) } @@ -191,11 +191,11 @@ func testFlags(args []string) (packageNames, passToTest []string) { } } - if cfg.TestCoverMode == "" { - cfg.TestCoverMode = "set" + if testCoverMode == "" { + testCoverMode = "set" if cfg.BuildRace { // Default coverage mode is atomic when -race is set. - cfg.TestCoverMode = "atomic" + testCoverMode = "atomic" } }