Commit d586aae1 authored by Cherry Zhang's avatar Cherry Zhang

test: errorcheck auto-generated functions

Add an "errorcheckwithauto" action which performs error check
including lines with auto-generated functions (excluded by
default). Comment "// ERRORAUTO" matches these lines.

Add testcase for CL 29570 (as an example).

Updates #16016, #17186.

Change-Id: Iaba3727336cd602f3dda6b9e5f97dafe0848e632
Reviewed-on: https://go-review.googlesource.com/29652
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 3dfb92f2
// errorcheck -0 -l -live -wb=0 // errorcheckwithauto -0 -l -live -wb=0
// +build !ppc64,!ppc64le // +build !ppc64,!ppc64le
// ppc64 needs a better tighten pass to make f18 pass // ppc64 needs a better tighten pass to make f18 pass
...@@ -658,3 +658,10 @@ func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$" ...@@ -658,3 +658,10 @@ func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$" func ddd2(a ...*int) { // ERROR "live at entry to ddd2: a$"
sink = a[0] sink = a[0]
} }
// issue 16016: autogenerated wrapper should have arguments live
type T struct{}
func (*T) Foo(ptr *int) {}
type R struct{ *T } // ERRORAUTO "live at entry to \(\*R\)\.Foo: \.this ptr" "live at entry to R\.Foo: \.this ptr"
...@@ -242,8 +242,7 @@ type test struct { ...@@ -242,8 +242,7 @@ type test struct {
donec chan bool // closed when done donec chan bool // closed when done
dt time.Duration dt time.Duration
src string src string
action string // "compile", "build", etc.
tempDir string tempDir string
err error err error
...@@ -457,15 +456,15 @@ func (t *test) run() { ...@@ -457,15 +456,15 @@ func (t *test) run() {
pkgPos = pos // some files are intentionally malformed pkgPos = pos // some files are intentionally malformed
} }
if ok, why := shouldTest(t.src[:pkgPos], goos, goarch); !ok { if ok, why := shouldTest(t.src[:pkgPos], goos, goarch); !ok {
t.action = "skip"
if *showSkips { if *showSkips {
fmt.Printf("%-20s %-20s: %s\n", t.action, t.goFileName(), why) fmt.Printf("%-20s %-20s: %s\n", "skip", t.goFileName(), why)
} }
return return
} }
var args, flags []string var args, flags []string
wantError := false wantError := false
wantAuto := false
singlefilepkgs := false singlefilepkgs := false
f := strings.Fields(action) f := strings.Fields(action)
if len(f) > 0 { if len(f) > 0 {
...@@ -477,27 +476,25 @@ func (t *test) run() { ...@@ -477,27 +476,25 @@ func (t *test) run() {
switch action { switch action {
case "rundircmpout": case "rundircmpout":
action = "rundir" action = "rundir"
t.action = "rundir"
case "cmpout": case "cmpout":
action = "run" // the run case already looks for <dir>/<test>.out files action = "run" // the run case already looks for <dir>/<test>.out files
fallthrough
case "compile", "compiledir", "build", "run", "runoutput", "rundir": case "compile", "compiledir", "build", "run", "runoutput", "rundir":
t.action = action // nothing to do
case "errorcheckandrundir": case "errorcheckandrundir":
wantError = false // should be no error if also will run wantError = false // should be no error if also will run
fallthrough case "errorcheckwithauto":
action = "errorcheck"
wantAuto = true
wantError = true
case "errorcheck", "errorcheckdir", "errorcheckoutput": case "errorcheck", "errorcheckdir", "errorcheckoutput":
t.action = action
wantError = true wantError = true
case "skip": case "skip":
if *runSkips { if *runSkips {
break break
} }
t.action = "skip"
return return
default: default:
t.err = skipError("skipped; unknown pattern: " + action) t.err = skipError("skipped; unknown pattern: " + action)
t.action = "??"
return return
} }
...@@ -574,7 +571,7 @@ func (t *test) run() { ...@@ -574,7 +571,7 @@ func (t *test) run() {
if *updateErrors { if *updateErrors {
t.updateErrors(string(out), long) t.updateErrors(string(out), long)
} }
t.err = t.errorCheck(string(out), long, t.gofile) t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
return return
case "compile": case "compile":
...@@ -622,7 +619,7 @@ func (t *test) run() { ...@@ -622,7 +619,7 @@ func (t *test) run() {
for _, name := range gofiles { for _, name := range gofiles {
fullshort = append(fullshort, filepath.Join(longdir, name), name) fullshort = append(fullshort, filepath.Join(longdir, name), name)
} }
t.err = t.errorCheck(string(out), fullshort...) t.err = t.errorCheck(string(out), wantAuto, fullshort...)
if t.err != nil { if t.err != nil {
break break
} }
...@@ -758,7 +755,7 @@ func (t *test) run() { ...@@ -758,7 +755,7 @@ func (t *test) run() {
return return
} }
} }
t.err = t.errorCheck(string(out), tfile, "tmp__.go") t.err = t.errorCheck(string(out), false, tfile, "tmp__.go")
return return
} }
} }
...@@ -801,7 +798,7 @@ func (t *test) expectedOutput() string { ...@@ -801,7 +798,7 @@ func (t *test) expectedOutput() string {
return string(b) return string(b)
} }
func splitOutput(out string) []string { func splitOutput(out string, wantAuto bool) []string {
// gc error messages continue onto additional lines with leading tabs. // gc error messages continue onto additional lines with leading tabs.
// Split the output at the beginning of each line that doesn't begin with a tab. // Split the output at the beginning of each line that doesn't begin with a tab.
// <autogenerated> lines are impossible to match so those are filtered out. // <autogenerated> lines are impossible to match so those are filtered out.
...@@ -812,7 +809,7 @@ func splitOutput(out string) []string { ...@@ -812,7 +809,7 @@ func splitOutput(out string) []string {
} }
if strings.HasPrefix(line, "\t") { if strings.HasPrefix(line, "\t") {
res[len(res)-1] += "\n" + line res[len(res)-1] += "\n" + line
} else if strings.HasPrefix(line, "go tool") || strings.HasPrefix(line, "<autogenerated>") || strings.HasPrefix(line, "#") { } else if strings.HasPrefix(line, "go tool") || strings.HasPrefix(line, "#") || !wantAuto && strings.HasPrefix(line, "<autogenerated>") {
continue continue
} else if strings.TrimSpace(line) != "" { } else if strings.TrimSpace(line) != "" {
res = append(res, line) res = append(res, line)
...@@ -821,14 +818,14 @@ func splitOutput(out string) []string { ...@@ -821,14 +818,14 @@ func splitOutput(out string) []string {
return res return res
} }
func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { func (t *test) errorCheck(outStr string, wantAuto bool, fullshort ...string) (err error) {
defer func() { defer func() {
if *verbose && err != nil { if *verbose && err != nil {
log.Printf("%s gc output:\n%s", t, outStr) log.Printf("%s gc output:\n%s", t, outStr)
} }
}() }()
var errs []error var errs []error
out := splitOutput(outStr) out := splitOutput(outStr, wantAuto)
// Cut directory name. // Cut directory name.
for i := range out { for i := range out {
...@@ -846,7 +843,11 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { ...@@ -846,7 +843,11 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
for _, we := range want { for _, we := range want {
var errmsgs []string var errmsgs []string
errmsgs, out = partitionStrings(we.prefix, out) if we.auto {
errmsgs, out = partitionStrings("<autogenerated>", out)
} else {
errmsgs, out = partitionStrings(we.prefix, out)
}
if len(errmsgs) == 0 { if len(errmsgs) == 0 {
errs = append(errs, fmt.Errorf("%s:%d: missing error %q", we.file, we.lineNum, we.reStr)) errs = append(errs, fmt.Errorf("%s:%d: missing error %q", we.file, we.lineNum, we.reStr))
continue continue
...@@ -906,7 +907,7 @@ func (t *test) updateErrors(out, file string) { ...@@ -906,7 +907,7 @@ func (t *test) updateErrors(out, file string) {
// Parse new errors. // Parse new errors.
errors := make(map[int]map[string]bool) errors := make(map[int]map[string]bool)
tmpRe := regexp.MustCompile(`autotmp_[0-9]+`) tmpRe := regexp.MustCompile(`autotmp_[0-9]+`)
for _, errStr := range splitOutput(out) { for _, errStr := range splitOutput(out, false) {
colon1 := strings.Index(errStr, ":") colon1 := strings.Index(errStr, ":")
if colon1 < 0 || errStr[:colon1] != file { if colon1 < 0 || errStr[:colon1] != file {
continue continue
...@@ -991,12 +992,14 @@ type wantedError struct { ...@@ -991,12 +992,14 @@ type wantedError struct {
reStr string reStr string
re *regexp.Regexp re *regexp.Regexp
lineNum int lineNum int
auto bool // match <autogenerated> line
file string file string
prefix string prefix string
} }
var ( var (
errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`) errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`)
errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`)
errQuotesRx = regexp.MustCompile(`"([^"]*)"`) errQuotesRx = regexp.MustCompile(`"([^"]*)"`)
lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`) lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
) )
...@@ -1011,7 +1014,13 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) { ...@@ -1011,7 +1014,13 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
// double comment disables ERROR // double comment disables ERROR
continue continue
} }
m := errRx.FindStringSubmatch(line) var auto bool
m := errAutoRx.FindStringSubmatch(line)
if m != nil {
auto = true
} else {
m = errRx.FindStringSubmatch(line)
}
if m == nil { if m == nil {
continue continue
} }
...@@ -1046,6 +1055,7 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) { ...@@ -1046,6 +1055,7 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
reStr: rx, reStr: rx,
re: re, re: re,
prefix: prefix, prefix: prefix,
auto: auto,
lineNum: lineNum, lineNum: lineNum,
file: short, file: short,
}) })
......
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