go/build: don't include imports from cgo files when CGO_ENABLED=0

Fixes #35873
Fixes #35946

Change-Id: I9f9a9c09006f8957569db6e5cc13382b9b28f829
Reviewed-on: https://go-review.googlesource.com/c/go/+/209660
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Jay Conrod 2019-12-03 15:02:10 -05:00
parent 7d1d944626
commit ae2e2446c2
6 changed files with 139 additions and 26 deletions

View File

@ -0,0 +1,85 @@
# Check that files and their imports are not included in 'go list' output
# when they are excluded by build constraints.
# Linux and cgo files should be included when building in that configuration.
env GOOS=linux
env CGO_ENABLED=1
go list -f '{{range .GoFiles}}{{.}} {{end}}'
stdout '^cgotag.go empty.go suffix_linux.go tag.go $'
go list -f '{{range .CgoFiles}}{{.}} {{end}}'
stdout '^cgoimport.go $'
go list -f '{{range .Imports}}{{.}} {{end}}'
stdout '^C cgoimport cgotag suffix tag $'
# Disabling cgo should exclude cgo files and their imports.
env CGO_ENABLED=0
go list -f '{{range .GoFiles}}{{.}} {{end}}'
stdout 'empty.go suffix_linux.go tag.go'
go list -f '{{range .CgoFiles}}{{.}} {{end}}'
! stdout .
go list -f '{{range .Imports}}{{.}} {{end}}'
stdout '^suffix tag $'
# Changing OS should exclude linux sources.
env GOOS=darwin
go list -f '{{range .GoFiles}}{{.}} {{end}}'
stdout '^empty.go $'
go list -f '{{range .Imports}}{{.}} {{end}}'
stdout '^$'
# Enabling a tag should include files that require it.
go list -tags=extra -f '{{range .GoFiles}}{{.}} {{end}}'
stdout '^empty.go extra.go $'
go list -tags=extra -f '{{range .Imports}}{{.}} {{end}}'
stdout '^extra $'
# Packages that require a tag should not be listed unless the tag is on.
! go list ./tagonly
go list -tags=extra ./tagonly
stdout m/tagonly
-- go.mod --
module m
go 1.13
-- empty.go --
package p
-- extra.go --
// +build extra
package p
import _ "extra"
-- suffix_linux.go --
package p
import _ "suffix"
-- tag.go --
// +build linux
package p
import _ "tag"
-- cgotag.go --
// +build cgo
package p
import _ "cgotag"
-- cgoimport.go --
package p
import "C"
import _ "cgoimport"
-- tagonly/tagonly.go --
// +build extra
package tagonly

View File

@ -1,10 +0,0 @@
env GO111MODULE=off
# go list supports -tags
go list -tags=thetag ./my...
stdout mypkg
-- mypkg/x.go --
// +build thetag
package mypkg

View File

@ -905,6 +905,11 @@ Found:
}
// Record imports and information about cgo.
type importPos struct {
path string
pos token.Pos
}
var fileImports []importPos
isCgo := false
for _, decl := range pf.Decls {
d, ok := decl.(*ast.GenDecl)
@ -921,13 +926,7 @@ Found:
if err != nil {
log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
}
if isXTest {
xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
} else if isTest {
testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
} else {
imported[path] = append(imported[path], fset.Position(spec.Pos()))
}
fileImports = append(fileImports, importPos{path, spec.Pos()})
if path == "C" {
if isTest {
badFile(fmt.Errorf("use of cgo in test %s not supported", filename))
@ -946,21 +945,37 @@ Found:
}
}
}
if isCgo {
var fileList *[]string
var importMap map[string][]token.Position
switch {
case isCgo:
allTags["cgo"] = true
if ctxt.CgoEnabled {
p.CgoFiles = append(p.CgoFiles, name)
fileList = &p.CgoFiles
importMap = imported
} else {
p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
// Ignore imports from cgo files if cgo is disabled.
fileList = &p.IgnoredGoFiles
}
case isXTest:
fileList = &p.XTestGoFiles
importMap = xTestImported
case isTest:
fileList = &p.TestGoFiles
importMap = testImported
default:
fileList = &p.GoFiles
importMap = imported
}
*fileList = append(*fileList, name)
if importMap != nil {
for _, imp := range fileImports {
importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos))
}
} else if isXTest {
p.XTestGoFiles = append(p.XTestGoFiles, name)
} else if isTest {
p.TestGoFiles = append(p.TestGoFiles, name)
} else {
p.GoFiles = append(p.GoFiles, name)
}
}
if badGoError != nil {
return p, badGoError
}

View File

@ -526,3 +526,20 @@ func TestMissingImportErrorRepetition(t *testing.T) {
t.Fatalf("package path %q appears in error %d times; should appear once\nerror: %v", pkgPath, n, err)
}
}
// TestCgoImportsIgnored checks that imports in cgo files are not included
// in the imports list when cgo is disabled.
// Verifies golang.org/issue/35946.
func TestCgoImportsIgnored(t *testing.T) {
ctxt := Default
ctxt.CgoEnabled = false
p, err := ctxt.ImportDir("testdata/cgo_disabled", 0)
if err != nil {
t.Fatal(err)
}
for _, path := range p.Imports {
if path == "should/be/ignored" {
t.Errorf("found import %q in ignored cgo file", path)
}
}
}

View File

@ -0,0 +1,5 @@
package cgo_disabled
import "C"
import _ "should/be/ignored"

View File

@ -0,0 +1 @@
package cgo_disabled