]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: run cover before cgo
authorRuss Cox <rsc@golang.org>
Fri, 10 Nov 2017 20:58:16 +0000 (15:58 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 16 Nov 2017 16:34:35 +0000 (16:34 +0000)
If we're running coverage on a package using cgo, we need to
apply both cmd/cover and cmd/cgo as source transformers.
To date we've applied cgo, then cover.

Cover is very sensitive to the exact character position of
expressions in its input, though, and cgo is not, so swap
them, applying first cover and then cgo.

The only drawback here is that coverage formerly applied
to SWIG-generated cgo files, and now it does not.
I am not convinced anyone depended critically on that,
and probably the later analysis with go tool cover would
have tried to parse the original .swig file as a Go file and
gotten very confused.

Fixes #8726.
Fixes #9212.
Fixes #9479.

Change-Id: I777c8b64f7726cb117d59e03073954abc6dfa34d
Reviewed-on: https://go-review.googlesource.com/77155
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/internal/work/exec.go

index 60e6cedda1c3b5dee2f6df9798f6d6a82fbc5e0e..43dbf40e51f1eef69da58a847a3c6d4b01b2393b 100644 (file)
@@ -390,6 +390,40 @@ func (b *Builder) build(a *Action) (err error) {
                cxxfiles = append(cxxfiles, outCXX...)
        }
 
+       // If we're doing coverage, preprocess the .go files and put them in the work directory
+       if a.Package.Internal.CoverMode != "" {
+               for i, file := range str.StringList(gofiles, cgofiles) {
+                       var sourceFile string
+                       var coverFile string
+                       var key string
+                       if strings.HasSuffix(file, ".cgo1.go") {
+                               // cgo files have absolute paths
+                               base := filepath.Base(file)
+                               sourceFile = file
+                               coverFile = objdir + base
+                               key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
+                       } else {
+                               sourceFile = filepath.Join(a.Package.Dir, file)
+                               coverFile = objdir + file
+                               key = file
+                       }
+                       coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go"
+                       cover := a.Package.Internal.CoverVars[key]
+                       if cover == nil || base.IsTestFile(file) {
+                               // Not covering this file.
+                               continue
+                       }
+                       if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
+                               return err
+                       }
+                       if i < len(gofiles) {
+                               gofiles[i] = coverFile
+                       } else {
+                               cgofiles[i-len(gofiles)] = coverFile
+                       }
+               }
+       }
+
        // Run cgo.
        if a.Package.UsesCgo() || a.Package.UsesSwig() {
                // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
@@ -445,35 +479,6 @@ func (b *Builder) build(a *Action) (err error) {
                return &load.NoGoError{Package: a.Package}
        }
 
-       // If we're doing coverage, preprocess the .go files and put them in the work directory
-       if a.Package.Internal.CoverMode != "" {
-               for i, file := range gofiles {
-                       var sourceFile string
-                       var coverFile string
-                       var key string
-                       if strings.HasSuffix(file, ".cgo1.go") {
-                               // cgo files have absolute paths
-                               base := filepath.Base(file)
-                               sourceFile = file
-                               coverFile = objdir + base
-                               key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
-                       } else {
-                               sourceFile = filepath.Join(a.Package.Dir, file)
-                               coverFile = objdir + file
-                               key = file
-                       }
-                       cover := a.Package.Internal.CoverVars[key]
-                       if cover == nil || base.IsTestFile(file) {
-                               // Not covering this file.
-                               continue
-                       }
-                       if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
-                               return err
-                       }
-                       gofiles[i] = coverFile
-               }
-       }
-
        // Prepare Go vet config if needed.
        var vcfg *vetConfig
        if a.needVet {