mirror of https://github.com/golang/go.git
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: Keith Randall <khr@golang.org>
This commit is contained in:
parent
3dfb92f254
commit
d586aae1f4
|
|
@ -1,4 +1,4 @@
|
||||||
// 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$"
|
||||||
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"
|
||||||
|
|
|
||||||
52
test/run.go
52
test/run.go
|
|
@ -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() {
|
||||||
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() {
|
||||||
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() {
|
||||||
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() {
|
||||||
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() {
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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) {
|
||||||
|
|
||||||
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) {
|
||||||
// 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 {
|
||||||
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) {
|
||||||
// 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) {
|
||||||
reStr: rx,
|
reStr: rx,
|
||||||
re: re,
|
re: re,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
|
auto: auto,
|
||||||
lineNum: lineNum,
|
lineNum: lineNum,
|
||||||
file: short,
|
file: short,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue