From: Russ Cox Date: Fri, 10 Nov 2017 20:58:16 +0000 (-0500) Subject: cmd/go: run cover before cgo X-Git-Tag: go1.10beta1~230 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5a7fd4039913f8bdb322b577ecf10a60ddcfedea;p=gostls13.git cmd/go: run cover before cgo 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 --- diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 60e6cedda1..43dbf40e51 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -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 {