tg.setenv("GOTMPDIR", tg.tempdir)
 
        tg.runFail("test", "coverbad")
-       tg.grepStderr(`coverbad[\\/]p.go:4`, "did not find correct line number for error")
+       tg.grepStderr(`coverbad[\\/]p\.go:4`, "did not find coverbad/p.go:4")
+       tg.grepStderr(`coverbad[\\/]p1\.go:6`, "did not find coverbad/p1.go:6")
        tg.grepStderrNot(regexp.QuoteMeta(tg.tempdir), "found temporary directory in error")
        stderr := tg.getStderr()
 
        tg.runFail("test", "-cover", "coverbad")
-       tg.grepStderr(`coverbad[\\/]p.go:4`, "did not find correct line number for error")
        stderr2 := tg.getStderr()
 
        // It's OK that stderr2 drops the character position in the error,
-       // because of the //line directive.
+       // because of the //line directive (see golang.org/issue/22662).
        stderr = strings.Replace(stderr, "p.go:4:2:", "p.go:4:", -1)
        if stderr != stderr2 {
                t.Logf("test -cover changed error messages:\nbefore:\n%s\n\nafter:\n%s", stderr, stderr2)
                t.Fatal(err)
        }
 
-       out, err = exec.Command("/bin/sh", sh).CombinedOutput()
+       out, err = exec.Command("/usr/bin/env", "bash", "-x", sh).CombinedOutput()
        if err != nil {
                t.Fatalf("/bin/sh %s: %v\n%s", sh, err, out)
        }
+       t.Logf("shell output:\n%s", out)
 
        out, err = exec.Command(obj).CombinedOutput()
        if err != nil {
 
                        sfiles = nil
                }
 
-               outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
+               outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(a.Package.Dir, cgofiles), objdirCgofiles, gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
                if err != nil {
                        return err
                }
                // so that vet's error messages will use absolute paths,
                // so that we can reformat them relative to the directory
                // in which the go command is invoked.
-               absfiles := make([]string, len(gofiles))
-               for i, f := range gofiles {
-                       if !filepath.IsAbs(f) {
-                               f = filepath.Join(a.Package.Dir, f)
-                       }
-                       absfiles[i] = f
-               }
                vcfg = &vetConfig{
                        Compiler:    cfg.BuildToolchainName,
                        Dir:         a.Package.Dir,
-                       GoFiles:     absfiles,
+                       GoFiles:     mkAbsFiles(a.Package.Dir, gofiles),
                        ImportMap:   make(map[string]string),
                        PackageFile: make(map[string]string),
                }
 // print this error.
 var errPrintedOutput = errors.New("already printed output - no need to show error")
 
-var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+(:[0-9]+)?\]`)
-var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
+var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
+var cgoTypeSigRe = regexp.MustCompile(`\b_C2?(type|func|var|macro)_\B`)
 
 // run runs the command given by cmdline in the directory dir.
 // If the command fails, run prints information about the failure
        gofiles := []string{objdir + "_cgo_gotypes.go"}
        cfiles := []string{"_cgo_export.c"}
        for _, fn := range cgofiles {
-               f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
-               gofiles = append(gofiles, objdir+f+"cgo1.go")
-               cfiles = append(cfiles, f+"cgo2.c")
+               f := strings.TrimSuffix(filepath.Base(fn), ".go")
+               gofiles = append(gofiles, objdir+f+".cgo1.go")
+               cfiles = append(cfiles, f+".cgo2.c")
        }
 
        // TODO: make cgo not depend on $GOARCH?
        }
        return ldflags
 }
+
+// mkAbsFiles converts files into a list of absolute files,
+// assuming they were originally relative to dir,
+// and returns that new list.
+func mkAbsFiles(dir string, files []string) []string {
+       abs := make([]string, len(files))
+       for i, f := range files {
+               if !filepath.IsAbs(f) {
+                       f = filepath.Join(dir, f)
+               }
+               abs[i] = f
+       }
+       return abs
+}