Commit 5a7fd403 authored by Russ Cox's avatar Russ Cox

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/77155Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 8c47aa15
......@@ -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 {
......
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