]> Cypherpunks repositories - gostls13.git/commitdiff
go/build: don't include imports from cgo files when CGO_ENABLED=0
authorJay Conrod <jayconrod@google.com>
Tue, 3 Dec 2019 20:02:10 +0000 (15:02 -0500)
committerJay Conrod <jayconrod@google.com>
Wed, 4 Dec 2019 21:29:42 +0000 (21:29 +0000)
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>
src/cmd/go/testdata/script/list_constraints.txt [new file with mode: 0644]
src/cmd/go/testdata/script/list_tags.txt [deleted file]
src/go/build/build.go
src/go/build/build_test.go
src/go/build/testdata/cgo_disabled/cgo_disabled.go [new file with mode: 0644]
src/go/build/testdata/cgo_disabled/empty.go [new file with mode: 0644]

diff --git a/src/cmd/go/testdata/script/list_constraints.txt b/src/cmd/go/testdata/script/list_constraints.txt
new file mode 100644 (file)
index 0000000..665670e
--- /dev/null
@@ -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
diff --git a/src/cmd/go/testdata/script/list_tags.txt b/src/cmd/go/testdata/script/list_tags.txt
deleted file mode 100644 (file)
index 49069bd..0000000
+++ /dev/null
@@ -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
index a4523a6eefe64b61e23a207b17e2a45be144cce9..62b70c26f12ff7464ef5b6903a1b1e1c53398096 100644 (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
        }
index 1d14731983da61d9ed2461c5cbf9d75f86c38388..80454871741cdb77cbb2a8f48c8e162356e61e03 100644 (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)
+               }
+       }
+}
diff --git a/src/go/build/testdata/cgo_disabled/cgo_disabled.go b/src/go/build/testdata/cgo_disabled/cgo_disabled.go
new file mode 100644 (file)
index 0000000..d1edb99
--- /dev/null
@@ -0,0 +1,5 @@
+package cgo_disabled
+
+import "C"
+
+import _ "should/be/ignored"
diff --git a/src/go/build/testdata/cgo_disabled/empty.go b/src/go/build/testdata/cgo_disabled/empty.go
new file mode 100644 (file)
index 0000000..63afe42
--- /dev/null
@@ -0,0 +1 @@
+package cgo_disabled