Commit bb3976df by Ian Lance Taylor

cmd/go, cmd/vet: make vet work with gccgo

    
    Backport https://golang.org/cl/113715 and https://golang.org/cl/113716:
    
    cmd/go: don't pass -compiler flag to vet
    
    Without this running go vet -compiler=gccgo causes vet to fail.
    The vet tool does need to know the compiler, but it is passed in
    vetConfig.Compiler.
    
    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 golang/go#25324).
    
    The result is that the cmd/go vet tests pass when using -compiler=gccgo.
    
    Reviewed-on: https://go-review.googlesource.com/114516

From-SVN: r260913
parent fc27db2b
572b19513766e9e5cc4aa8d984a89c93880726ba 9731580e76c065b76e3a103356bb8920da05a685
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -1010,7 +1010,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { ...@@ -1010,7 +1010,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
// Cgo translation adds imports of "runtime/cgo" and "syscall", // Cgo translation adds imports of "runtime/cgo" and "syscall",
// except for certain packages, to avoid circular dependencies. // 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") addImport("runtime/cgo")
} }
if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
...@@ -1019,7 +1019,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { ...@@ -1019,7 +1019,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
// SWIG adds imports of some standard packages. // SWIG adds imports of some standard packages.
if p.UsesSwig() { if p.UsesSwig() {
addImport("runtime/cgo") if cfg.BuildContext.Compiler != "gccgo" {
addImport("runtime/cgo")
}
addImport("syscall") addImport("syscall")
addImport("sync") addImport("sync")
...@@ -1225,7 +1227,7 @@ func LinkerDeps(p *Package) []string { ...@@ -1225,7 +1227,7 @@ func LinkerDeps(p *Package) []string {
deps := []string{"runtime"} deps := []string{"runtime"}
// External linking mode forces an import of runtime/cgo. // External linking mode forces an import of runtime/cgo.
if externalLinkingForced(p) { if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
deps = append(deps, "runtime/cgo") deps = append(deps, "runtime/cgo")
} }
// On ARM with GOARM=5, it forces an import of math, for soft floating point. // On ARM with GOARM=5, it forces an import of math, for soft floating point.
......
...@@ -90,7 +90,7 @@ func vetFlags(args []string) (passToVet, packageNames []string) { ...@@ -90,7 +90,7 @@ func vetFlags(args []string) (passToVet, packageNames []string) {
} }
switch f.Name { switch f.Name {
// Flags known to the build but not to vet, so must be dropped. // Flags known to the build but not to vet, so must be dropped.
case "x", "n", "vettool": case "x", "n", "vettool", "compiler":
if extraWord { if extraWord {
args = append(args[:i], args[i+2:]...) args = append(args[:i], args[i+2:]...)
extraWord = false extraWord = false
......
...@@ -512,6 +512,7 @@ func (b *Builder) build(a *Action) (err error) { ...@@ -512,6 +512,7 @@ func (b *Builder) build(a *Action) (err error) {
ImportPath: a.Package.ImportPath, ImportPath: a.Package.ImportPath,
ImportMap: make(map[string]string), ImportMap: make(map[string]string),
PackageFile: make(map[string]string), PackageFile: make(map[string]string),
Standard: make(map[string]bool),
} }
a.vetCfg = vcfg a.vetCfg = vcfg
for i, raw := range a.Package.Internal.RawImports { for i, raw := range a.Package.Internal.RawImports {
...@@ -548,17 +549,24 @@ func (b *Builder) build(a *Action) (err error) { ...@@ -548,17 +549,24 @@ func (b *Builder) build(a *Action) (err error) {
for _, a1 := range a.Deps { for _, a1 := range a.Deps {
p1 := a1.Package p1 := a1.Package
if p1 == nil || p1.ImportPath == "" || a1.built == "" { if p1 == nil || p1.ImportPath == "" {
continue continue
} }
fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built) if a1.built != "" {
fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
}
if vcfg != nil { if vcfg != nil {
// Add import mapping if needed // Add import mapping if needed
// (for imports like "runtime/cgo" that appear only in generated code). // (for imports like "runtime/cgo" that appear only in generated code).
if !vcfgMapped[p1.ImportPath] { if !vcfgMapped[p1.ImportPath] {
vcfg.ImportMap[p1.ImportPath] = 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
}
} }
} }
...@@ -693,6 +701,7 @@ type vetConfig struct { ...@@ -693,6 +701,7 @@ type vetConfig struct {
GoFiles []string GoFiles []string
ImportMap map[string]string ImportMap map[string]string
PackageFile map[string]string PackageFile map[string]string
Standard map[string]bool
ImportPath string ImportPath string
SucceedOnTypecheckFailure bool SucceedOnTypecheckFailure bool
...@@ -722,7 +731,10 @@ func (b *Builder) vet(a *Action) error { ...@@ -722,7 +731,10 @@ func (b *Builder) vet(a *Action) error {
if vcfg.ImportMap["fmt"] == "" { if vcfg.ImportMap["fmt"] == "" {
a1 := a.Deps[1] a1 := a.Deps[1]
vcfg.ImportMap["fmt"] = "fmt" 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. // During go test, ignore type-checking failures during vet.
......
...@@ -292,6 +292,7 @@ type vetConfig struct { ...@@ -292,6 +292,7 @@ type vetConfig struct {
GoFiles []string GoFiles []string
ImportMap map[string]string ImportMap map[string]string
PackageFile map[string]string PackageFile map[string]string
Standard map[string]bool
SucceedOnTypecheckFailure bool SucceedOnTypecheckFailure bool
...@@ -309,7 +310,12 @@ func (v *vetConfig) Import(path string) (*types.Package, error) { ...@@ -309,7 +310,12 @@ func (v *vetConfig) Import(path string) (*types.Package, error) {
if p == "" { if p == "" {
return nil, fmt.Errorf("unknown import path %q", path) return nil, fmt.Errorf("unknown import path %q", path)
} }
if v.PackageFile[p] == "" && v.Compiler != "gccgo" { 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 nil, fmt.Errorf("unknown package file for import %q", path)
} }
return v.imp.Import(p) return v.imp.Import(p)
...@@ -318,6 +324,10 @@ func (v *vetConfig) Import(path string) (*types.Package, error) { ...@@ -318,6 +324,10 @@ func (v *vetConfig) Import(path string) (*types.Package, error) {
func (v *vetConfig) openPackageFile(path string) (io.ReadCloser, error) { func (v *vetConfig) openPackageFile(path string) (io.ReadCloser, error) {
file := v.PackageFile[path] file := v.PackageFile[path]
if file == "" { 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, // Note that path here has been translated via v.ImportMap,
// unlike in the error in Import above. We prefer the error in // unlike in the error in Import above. We prefer the error in
// Import, but it's worth diagnosing this one too, just in case. // Import, but it's worth diagnosing this one too, just in case.
......
...@@ -176,7 +176,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo ...@@ -176,7 +176,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo
return p, nil return p, nil
} }
rc, err := lookup(pkgpath) rc, err := lookup(pkgpath)
if err == nil { if err == nil && rc != nil {
defer rc.Close() defer rc.Close()
rs, ok := rc.(io.ReadSeeker) rs, ok := rc.(io.ReadSeeker)
if !ok { if !ok {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment