From: Ian Lance Taylor Date: Fri, 18 May 2018 13:18:34 +0000 (-0400) Subject: cmd/go, cmd/vet, go/internal/gccgoimport: make vet work with gccgo X-Git-Tag: go1.11beta1~312 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=30b6bc30b208299e4cb6598be854ec276db85661;p=gostls13.git cmd/go, cmd/vet, go/internal/gccgoimport: make vet work with gccgo When using gccgo/GoLLVM, there is no package file for a standard library package. Since it is impossible for the go tool to rebuild the package, and since the package file exists only in the form of a .gox file, this seems like the best choice. Unfortunately it was confusing vet, which wanted to see a real file. This caused vet to report errors about missing package files for standard library packages. The gccgoimporter knows how to correctly handle this case. Fix this by 1) telling vet which packages are standard; 2) letting vet skip those packages; 3) letting the gccgoimporter handle this case. As a separate required fix, gccgo/GoLLVM has no runtime/cgo package, so don't try to depend on it (as it happens, this fixes #25324). The result is that the cmd/go vet tests pass when using -compiler=gccgo. Fixes #25324 Change-Id: Iba8f948fe944da5dc674f580bd3321929ee50fa0 Reviewed-on: https://go-review.googlesource.com/113716 Run-TryBot: Ian Lance Taylor Reviewed-by: Bryan C. Mills Reviewed-by: Than McIntosh TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index b81b4e98dc..5a26ca7892 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -999,7 +999,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // Cgo translation adds imports of "runtime/cgo" and "syscall", // except for certain packages, to avoid circular dependencies. - if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) { + if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" { addImport("runtime/cgo") } if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { @@ -1008,7 +1008,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // SWIG adds imports of some standard packages. if p.UsesSwig() { - addImport("runtime/cgo") + if cfg.BuildContext.Compiler != "gccgo" { + addImport("runtime/cgo") + } addImport("syscall") addImport("sync") @@ -1214,7 +1216,7 @@ func LinkerDeps(p *Package) []string { deps := []string{"runtime"} // External linking mode forces an import of runtime/cgo. - if externalLinkingForced(p) { + if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" { deps = append(deps, "runtime/cgo") } // On ARM with GOARM=5, it forces an import of math, for soft floating point. diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 9cb568a18f..072e2904c1 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -743,6 +743,7 @@ type vetConfig struct { GoFiles []string ImportMap map[string]string PackageFile map[string]string + Standard map[string]bool ImportPath string SucceedOnTypecheckFailure bool @@ -760,6 +761,7 @@ func buildVetConfig(a *Action, gofiles []string) { ImportPath: a.Package.ImportPath, ImportMap: make(map[string]string), PackageFile: make(map[string]string), + Standard: make(map[string]bool), } a.vetCfg = vcfg for i, raw := range a.Package.Internal.RawImports { @@ -776,7 +778,7 @@ func buildVetConfig(a *Action, gofiles []string) { for _, a1 := range a.Deps { p1 := a1.Package - if p1 == nil || p1.ImportPath == "" || a1.built == "" { + if p1 == nil || p1.ImportPath == "" { continue } // Add import mapping if needed @@ -784,7 +786,12 @@ func buildVetConfig(a *Action, gofiles []string) { if !vcfgMapped[p1.ImportPath] { vcfg.ImportMap[p1.ImportPath] = p1.ImportPath } - vcfg.PackageFile[p1.ImportPath] = a1.built + if a1.built != "" { + vcfg.PackageFile[p1.ImportPath] = a1.built + } + if p1.Standard { + vcfg.Standard[p1.ImportPath] = true + } } } @@ -812,7 +819,10 @@ func (b *Builder) vet(a *Action) error { if vcfg.ImportMap["fmt"] == "" { a1 := a.Deps[1] vcfg.ImportMap["fmt"] = "fmt" - vcfg.PackageFile["fmt"] = a1.built + if a1.built != "" { + vcfg.PackageFile["fmt"] = a1.built + } + vcfg.Standard["fmt"] = true } // During go test, ignore type-checking failures during vet. diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go index 7265aa6f57..4422add72f 100644 --- a/src/cmd/vet/main.go +++ b/src/cmd/vet/main.go @@ -294,6 +294,7 @@ type vetConfig struct { GoFiles []string ImportMap map[string]string PackageFile map[string]string + Standard map[string]bool SucceedOnTypecheckFailure bool @@ -312,6 +313,11 @@ func (v *vetConfig) Import(path string) (*types.Package, error) { return nil, fmt.Errorf("unknown import path %q", path) } if v.PackageFile[p] == "" { + if v.Compiler == "gccgo" && v.Standard[path] { + // gccgo doesn't have sources for standard library packages, + // but the importer will do the right thing. + return v.imp.Import(path) + } return nil, fmt.Errorf("unknown package file for import %q", path) } return v.imp.Import(p) @@ -320,6 +326,10 @@ func (v *vetConfig) Import(path string) (*types.Package, error) { func (v *vetConfig) openPackageFile(path string) (io.ReadCloser, error) { file := v.PackageFile[path] if file == "" { + if v.Compiler == "gccgo" && v.Standard[path] { + // The importer knows how to handle this. + return nil, nil + } // Note that path here has been translated via v.ImportMap, // unlike in the error in Import above. We prefer the error in // Import, but it's worth diagnosing this one too, just in case. diff --git a/src/go/internal/gccgoimporter/importer.go b/src/go/internal/gccgoimporter/importer.go index 46544233dd..d4998cf2a2 100644 --- a/src/go/internal/gccgoimporter/importer.go +++ b/src/go/internal/gccgoimporter/importer.go @@ -151,14 +151,17 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo var reader io.ReadSeeker var fpath string + var rc io.ReadCloser if lookup != nil { if p := imports[pkgpath]; p != nil && p.Complete() { return p, nil } - rc, err := lookup(pkgpath) + rc, err = lookup(pkgpath) if err != nil { return nil, err } + } + if rc != nil { defer rc.Close() rs, ok := rc.(io.ReadSeeker) if !ok {