Update linux-x86 Go prebuilts from ab/8003217 (1.18beta1)
https://ci.android.com/builds/branches/aosp-build-tools-release/grid?head=8003217&tail=8003217
Update script: toolchain/go/update-prebuilts.sh
Test: Treehugger presubmit
Change-Id: I4b89c374ccd78d5695b355cfe423d307fac1d2e9
diff --git a/test/run.go b/test/run.go
index d7f5d02..37be958 100644
--- a/test/run.go
+++ b/test/run.go
@@ -9,6 +9,7 @@
import (
"bytes"
+ "encoding/json"
"errors"
"flag"
"fmt"
@@ -31,6 +32,10 @@
"unicode"
)
+// CompilerDefaultGLevel is the -G level used by default when not overridden by a
+// command-line flag
+const CompilerDefaultGLevel = 3
+
var (
verbose = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.")
keep = flag.Bool("k", false, "keep. keep temporary directory.")
@@ -42,11 +47,55 @@
linkshared = flag.Bool("linkshared", false, "")
updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output")
runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
+ force = flag.Bool("f", false, "ignore expected-failure test lists")
+ generics = flag.String("G", defaultGLevels, "a comma-separated list of -G compiler flags to test with")
shard = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.")
shards = flag.Int("shards", 0, "number of shards. If 0, all tests are run. This is used by the continuous build.")
)
+type envVars struct {
+ GOOS string
+ GOARCH string
+ GOEXPERIMENT string
+ CGO_ENABLED string
+}
+
+var env = func() (res envVars) {
+ cmd := exec.Command("go", "env", "-json")
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ log.Fatal("StdoutPipe:", err)
+ }
+ if err := cmd.Start(); err != nil {
+ log.Fatal("Start:", err)
+ }
+ if err := json.NewDecoder(stdout).Decode(&res); err != nil {
+ log.Fatal("Decode:", err)
+ }
+ if err := cmd.Wait(); err != nil {
+ log.Fatal("Wait:", err)
+ }
+ return
+}()
+
+var unifiedEnabled, defaultGLevels = func() (bool, string) {
+ // TODO(mdempsky): This will give false negatives if the unified
+ // experiment is enabled by default, but presumably at that point we
+ // won't need to disable tests for it anymore anyway.
+ enabled := strings.Contains(","+env.GOEXPERIMENT+",", ",unified,")
+
+ // Test both -G=0 and -G=3 on the longtest builders, to make sure we
+ // don't accidentally break -G=0 mode until we're ready to remove it
+ // completely. But elsewhere, testing -G=3 alone should be enough.
+ glevels := "3"
+ if strings.Contains(os.Getenv("GO_BUILDER_NAME"), "longtest") {
+ glevels = "0,3"
+ }
+
+ return enabled, glevels
+}()
+
// defaultAllCodeGen returns the default value of the -all_codegen
// flag. By default, we prefer to be fast (returning false), except on
// the linux-amd64 builder that's already very fast, so we get more
@@ -56,12 +105,13 @@
}
var (
- goos, goarch string
- cgoEnabled bool
+ goos = env.GOOS
+ goarch = env.GOARCH
+ cgoEnabled, _ = strconv.ParseBool(env.CGO_ENABLED)
// dirs are the directories to look for *.go files in.
// TODO(bradfitz): just use all directories?
- dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "abi", "typeparam"}
+ dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "abi", "typeparam", "typeparam/mdempsky"}
// ratec controls the max number of tests running at a time.
ratec chan bool
@@ -82,11 +132,13 @@
func main() {
flag.Parse()
- goos = getenv("GOOS", runtime.GOOS)
- goarch = getenv("GOARCH", runtime.GOARCH)
- cgoEnv, err := exec.Command(goTool(), "env", "CGO_ENABLED").Output()
- if err == nil {
- cgoEnabled, _ = strconv.ParseBool(strings.TrimSpace(string(cgoEnv)))
+ var glevels []int
+ for _, s := range strings.Split(*generics, ",") {
+ glevel, err := strconv.Atoi(s)
+ if err != nil {
+ log.Fatalf("invalid -G flag: %v", err)
+ }
+ glevels = append(glevels, glevel)
}
findExecCmd()
@@ -113,11 +165,11 @@
}
if fi, err := os.Stat(arg); err == nil && fi.IsDir() {
for _, baseGoFile := range goFiles(arg) {
- tests = append(tests, startTest(arg, baseGoFile))
+ tests = append(tests, startTests(arg, baseGoFile, glevels)...)
}
} else if strings.HasSuffix(arg, ".go") {
dir, file := filepath.Split(arg)
- tests = append(tests, startTest(dir, file))
+ tests = append(tests, startTests(dir, file, glevels)...)
} else {
log.Fatalf("can't yet deal with non-directory and non-go file %q", arg)
}
@@ -125,7 +177,7 @@
} else {
for _, dir := range dirs {
for _, baseGoFile := range goFiles(dir) {
- tests = append(tests, startTest(dir, baseGoFile))
+ tests = append(tests, startTests(dir, baseGoFile, glevels)...)
}
}
}
@@ -142,8 +194,15 @@
status = "FAIL"
}
if test.err != nil {
- status = "FAIL"
errStr = test.err.Error()
+ if test.expectFail {
+ errStr += " (expected)"
+ } else {
+ status = "FAIL"
+ }
+ } else if test.expectFail {
+ status = "FAIL"
+ errStr = "unexpected success"
}
if status == "FAIL" {
failed = true
@@ -151,7 +210,8 @@
resCount[status]++
dt := fmt.Sprintf("%.3fs", test.dt.Seconds())
if status == "FAIL" {
- fmt.Printf("# go run run.go -- %s\n%s\nFAIL\t%s\t%s\n",
+ fmt.Printf("# go run run.go -G=%v %s\n%s\nFAIL\t%s\t%s\n",
+ test.glevel,
path.Join(test.dir, test.gofile),
errStr, test.goFileName(), dt)
continue
@@ -270,30 +330,78 @@
dir, gofile string
donec chan bool // closed when done
dt time.Duration
+ glevel int // what -G level this test should use
src string
tempDir string
err error
+
+ // expectFail indicates whether the (overall) test recipe is
+ // expected to fail under the current test configuration (e.g., -G=3
+ // or GOEXPERIMENT=unified).
+ expectFail bool
}
-// startTest
-func startTest(dir, gofile string) *test {
- t := &test{
- dir: dir,
- gofile: gofile,
- donec: make(chan bool, 1),
+// initExpectFail initializes t.expectFail based on the build+test
+// configuration.
+func (t *test) initExpectFail(hasGFlag bool) {
+ if *force {
+ return
}
- if toRun == nil {
- toRun = make(chan *test, maxTests)
- go runTests()
+
+ if t.glevel == 0 && !hasGFlag && !unifiedEnabled {
+ // tests should always pass when run w/o types2 (i.e., using the
+ // legacy typechecker, option -G=0).
+ return
}
- select {
- case toRun <- t:
- default:
- panic("toRun buffer size (maxTests) is too small")
+
+ failureSets := []map[string]bool{types2Failures}
+
+ // Note: gccgo supports more 32-bit architectures than this, but
+ // hopefully the 32-bit failures are fixed before this matters.
+ switch goarch {
+ case "386", "arm", "mips", "mipsle":
+ failureSets = append(failureSets, types2Failures32Bit)
}
- return t
+
+ if unifiedEnabled {
+ failureSets = append(failureSets, unifiedFailures)
+ } else {
+ failureSets = append(failureSets, g3Failures)
+ }
+
+ filename := strings.Replace(t.goFileName(), "\\", "/", -1) // goFileName() uses \ on Windows
+
+ for _, set := range failureSets {
+ if set[filename] {
+ t.expectFail = true
+ return
+ }
+ }
+}
+
+func startTests(dir, gofile string, glevels []int) []*test {
+ tests := make([]*test, len(glevels))
+ for i, glevel := range glevels {
+ t := &test{
+ dir: dir,
+ gofile: gofile,
+ glevel: glevel,
+ donec: make(chan bool, 1),
+ }
+ if toRun == nil {
+ toRun = make(chan *test, maxTests)
+ go runTests()
+ }
+ select {
+ case toRun <- t:
+ default:
+ panic("toRun buffer size (maxTests) is too small")
+ }
+ tests[i] = t
+ }
+ return tests
}
// runTests runs tests in parallel, but respecting the order they
@@ -427,9 +535,9 @@
if name == "" {
return false
}
- if i := strings.Index(name, ","); i >= 0 {
+ if first, rest, ok := strings.Cut(name, ","); ok {
// comma-separated list
- return ctxt.match(name[:i]) && ctxt.match(name[i+1:])
+ return ctxt.match(first) && ctxt.match(rest)
}
if strings.HasPrefix(name, "!!") { // bad syntax, reject always
return false
@@ -480,12 +588,16 @@
// This must match the flags used for building the standard library,
// or else the commands will rebuild any needed packages (like runtime)
// over and over.
-func goGcflags() string {
- return "-gcflags=all=" + os.Getenv("GO_GCFLAGS")
+func (t *test) goGcflags() string {
+ flags := os.Getenv("GO_GCFLAGS")
+ if t.glevel != CompilerDefaultGLevel {
+ flags = fmt.Sprintf("%s -G=%v", flags, t.glevel)
+ }
+ return "-gcflags=all=" + flags
}
-func goGcflagsIsEmpty() bool {
- return "" == os.Getenv("GO_GCFLAGS")
+func (t *test) goGcflagsIsEmpty() bool {
+ return "" == os.Getenv("GO_GCFLAGS") && t.glevel == CompilerDefaultGLevel
}
var errTimeout = errors.New("command exceeded time limit")
@@ -510,24 +622,23 @@
}
// Execution recipe stops at first blank line.
- pos := strings.Index(t.src, "\n\n")
- if pos == -1 {
+ action, _, ok := strings.Cut(t.src, "\n\n")
+ if !ok {
t.err = fmt.Errorf("double newline ending execution recipe not found in %s", t.goFileName())
return
}
- action := t.src[:pos]
- if nl := strings.Index(action, "\n"); nl >= 0 && strings.Contains(action[:nl], "+build") {
+ if firstLine, rest, ok := strings.Cut(action, "\n"); ok && strings.Contains(firstLine, "+build") {
// skip first line
- action = action[nl+1:]
+ action = rest
}
action = strings.TrimPrefix(action, "//")
// Check for build constraints only up to the actual code.
- pkgPos := strings.Index(t.src, "\npackage")
- if pkgPos == -1 {
- pkgPos = pos // some files are intentionally malformed
+ header, _, ok := strings.Cut(t.src, "\npackage")
+ if !ok {
+ header = action // some files are intentionally malformed
}
- if ok, why := shouldTest(t.src[:pkgPos], goos, goarch); !ok {
+ if ok, why := shouldTest(header, goos, goarch); !ok {
if *showSkips {
fmt.Printf("%-20s %-20s: %s\n", "skip", t.goFileName(), why)
}
@@ -541,7 +652,11 @@
singlefilepkgs := false
setpkgpaths := false
localImports := true
- f := strings.Fields(action)
+ f, err := splitQuoted(action)
+ if err != nil {
+ t.err = fmt.Errorf("invalid test recipe: %v", err)
+ return
+ }
if len(f) > 0 {
action = f[0]
args = f[1:]
@@ -569,6 +684,8 @@
return
}
+ goexp := env.GOEXPERIMENT
+
// collect flags
for len(args) > 0 && strings.HasPrefix(args[0], "-") {
switch args[0] {
@@ -595,7 +712,11 @@
}
case "-goexperiment": // set GOEXPERIMENT environment
args = args[1:]
- runenv = append(runenv, "GOEXPERIMENT="+args[0])
+ if goexp != "" {
+ goexp += ","
+ }
+ goexp += args[0]
+ runenv = append(runenv, "GOEXPERIMENT="+goexp)
default:
flags = append(flags, args[0])
@@ -616,6 +737,60 @@
}
}
+ type Tool int
+
+ const (
+ _ Tool = iota
+ AsmCheck
+ Build
+ Run
+ Compile
+ )
+
+ // validForGLevel reports whether the current test is valid to run
+ // at the specified -G level. If so, it may update flags as
+ // necessary to test with -G.
+ validForGLevel := func(tool Tool) bool {
+ hasGFlag := false
+ for _, flag := range flags {
+ if strings.Contains(flag, "-G") {
+ hasGFlag = true
+ }
+ }
+
+ // In unified IR mode, run the test regardless of explicit -G flag.
+ if !unifiedEnabled && hasGFlag && t.glevel != CompilerDefaultGLevel {
+ // test provides explicit -G flag already; don't run again
+ if *verbose {
+ fmt.Printf("excl\t%s\n", t.goFileName())
+ }
+ return false
+ }
+
+ t.initExpectFail(hasGFlag)
+
+ switch tool {
+ case Build, Run:
+ // ok; handled in goGcflags
+
+ case Compile:
+ if !hasGFlag {
+ flags = append(flags, fmt.Sprintf("-G=%v", t.glevel))
+ }
+
+ default:
+ if t.glevel != CompilerDefaultGLevel {
+ // we don't know how to add -G for this test yet
+ if *verbose {
+ fmt.Printf("excl\t%s\n", t.goFileName())
+ }
+ return false
+ }
+ }
+
+ return true
+ }
+
t.makeTempDir()
if !*keep {
defer os.RemoveAll(t.tempDir)
@@ -692,6 +867,10 @@
t.err = fmt.Errorf("unimplemented action %q", action)
case "asmcheck":
+ if !validForGLevel(AsmCheck) {
+ return
+ }
+
// Compile Go file and match the generated assembly
// against a set of regexps in comments.
ops := t.wantedAsmOpcodes(long)
@@ -746,6 +925,10 @@
return
case "errorcheck":
+ if !validForGLevel(Compile) {
+ return
+ }
+
// Compile Go file.
// Fail if wantError is true and compilation was successful and vice versa.
// Match errors produced by gc against errors in comments.
@@ -774,72 +957,20 @@
t.updateErrors(string(out), long)
}
t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
- if t.err != nil {
- return // don't hide error if run below succeeds
- }
-
- // The following is temporary scaffolding to get types2 typechecker
- // up and running against the existing test cases. The explicitly
- // listed files don't pass yet, usually because the error messages
- // are slightly different (this list is not complete). Any errorcheck
- // tests that require output from analysis phases past initial type-
- // checking are also excluded since these phases are not running yet.
- // We can get rid of this code once types2 is fully plugged in.
-
- // For now we're done when we can't handle the file or some of the flags.
- // The first goal is to eliminate the excluded list; the second goal is to
- // eliminate the flag list.
-
- // Excluded files.
- filename := strings.Replace(t.goFileName(), "\\", "/", -1) // goFileName() uses \ on Windows
- if excluded[filename] {
- if *verbose {
- fmt.Printf("excl\t%s\n", filename)
- }
- return // cannot handle file yet
- }
-
- // Excluded flags.
- for _, flag := range flags {
- for _, pattern := range []string{
- "-m",
- } {
- if strings.Contains(flag, pattern) {
- if *verbose {
- fmt.Printf("excl\t%s\t%s\n", filename, flags)
- }
- return // cannot handle flag
- }
- }
- }
-
- // Run errorcheck again with -G option (new typechecker).
- cmdline = []string{goTool(), "tool", "compile", "-G=3", "-C", "-e", "-o", "a.o"}
- // No need to add -dynlink even if linkshared if we're just checking for errors...
- cmdline = append(cmdline, flags...)
- cmdline = append(cmdline, long)
- out, err = runcmd(cmdline...)
- if wantError {
- if err == nil {
- t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
- return
- }
- } else {
- if err != nil {
- t.err = err
- return
- }
- }
- if *updateErrors {
- t.updateErrors(string(out), long)
- }
- t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
case "compile":
+ if !validForGLevel(Compile) {
+ return
+ }
+
// Compile Go file.
_, t.err = compileFile(runcmd, long, flags)
case "compiledir":
+ if !validForGLevel(Compile) {
+ return
+ }
+
// Compile all files in the directory as packages in lexicographic order.
longdir := filepath.Join(cwd, t.goDirName())
pkgs, err := goDirPackages(longdir, singlefilepkgs)
@@ -855,6 +986,10 @@
}
case "errorcheckdir", "errorcheckandrundir":
+ if !validForGLevel(Compile) {
+ return
+ }
+
flags = append(flags, "-d=panic")
// Compile and errorCheck all files in the directory as packages in lexicographic order.
// If errorcheckdir and wantError, compilation of the last package must fail.
@@ -900,6 +1035,10 @@
fallthrough
case "rundir":
+ if !validForGLevel(Run) {
+ return
+ }
+
// Compile all files in the directory as packages in lexicographic order.
// In case of errorcheckandrundir, ignore failed compilation of the package before the last.
// Link as if the last file is the main package, run it.
@@ -958,6 +1097,10 @@
}
case "runindir":
+ if !validForGLevel(Run) {
+ return
+ }
+
// Make a shallow copy of t.goDirName() in its own module and GOPATH, and
// run "go run ." in it. The module path (and hence import path prefix) of
// the copy is equal to the basename of the source directory.
@@ -983,7 +1126,7 @@
return
}
- cmd := []string{goTool(), "run", goGcflags()}
+ cmd := []string{goTool(), "run", t.goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -997,13 +1140,21 @@
t.checkExpectedOutput(out)
case "build":
+ if !validForGLevel(Build) {
+ return
+ }
+
// Build Go file.
- _, err := runcmd(goTool(), "build", goGcflags(), "-o", "a.exe", long)
+ _, err := runcmd(goTool(), "build", t.goGcflags(), "-o", "a.exe", long)
if err != nil {
t.err = err
}
case "builddir", "buildrundir":
+ if !validForGLevel(Build) {
+ return
+ }
+
// Build an executable from all the .go and .s files in a subdirectory.
// Run it and verify its output in the buildrundir case.
longdir := filepath.Join(cwd, t.goDirName())
@@ -1083,10 +1234,14 @@
}
case "buildrun":
+ if !validForGLevel(Build) {
+ return
+ }
+
// Build an executable from Go file, then run it, verify its output.
// Useful for timeout tests where failure mode is infinite loop.
// TODO: not supported on NaCl
- cmd := []string{goTool(), "build", goGcflags(), "-o", "a.exe"}
+ cmd := []string{goTool(), "build", t.goGcflags(), "-o", "a.exe"}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -1108,13 +1263,17 @@
t.checkExpectedOutput(out)
case "run":
+ if !validForGLevel(Run) {
+ return
+ }
+
// Run Go file if no special go command flags are provided;
// otherwise build an executable and run it.
// Verify the output.
runInDir = ""
var out []byte
var err error
- if len(flags)+len(args) == 0 && goGcflagsIsEmpty() && !*linkshared && goarch == runtime.GOARCH && goos == runtime.GOOS {
+ if len(flags)+len(args) == 0 && t.goGcflagsIsEmpty() && !*linkshared && goarch == runtime.GOARCH && goos == runtime.GOOS && goexp == env.GOEXPERIMENT {
// If we're not using special go command flags,
// skip all the go command machinery.
// This avoids any time the go command would
@@ -1136,7 +1295,7 @@
}
out, err = runcmd(append([]string{exe}, args...)...)
} else {
- cmd := []string{goTool(), "run", goGcflags()}
+ cmd := []string{goTool(), "run", t.goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -1151,6 +1310,10 @@
t.checkExpectedOutput(out)
case "runoutput":
+ if !validForGLevel(Run) {
+ return
+ }
+
// Run Go file and write its output into temporary Go file.
// Run generated Go file and verify its output.
rungatec <- true
@@ -1158,7 +1321,7 @@
<-rungatec
}()
runInDir = ""
- cmd := []string{goTool(), "run", goGcflags()}
+ cmd := []string{goTool(), "run", t.goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -1173,7 +1336,7 @@
t.err = fmt.Errorf("write tempfile:%s", err)
return
}
- cmd = []string{goTool(), "run", goGcflags()}
+ cmd = []string{goTool(), "run", t.goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -1186,10 +1349,14 @@
t.checkExpectedOutput(out)
case "errorcheckoutput":
+ if !validForGLevel(Compile) {
+ return
+ }
+
// Run Go file and write its output into temporary Go file.
// Compile and errorCheck generated Go file.
runInDir = ""
- cmd := []string{goTool(), "run", goGcflags()}
+ cmd := []string{goTool(), "run", t.goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -1348,8 +1515,8 @@
// Assume errmsg says "file:line: foo".
// Cut leading "file:line: " to avoid accidental matching of file name instead of message.
text := errmsg
- if i := strings.Index(text, " "); i >= 0 {
- text = text[i+1:]
+ if _, suffix, ok := strings.Cut(text, " "); ok {
+ text = suffix
}
if we.re.MatchString(text) {
matched = true
@@ -1394,31 +1561,26 @@
}
lines := strings.Split(string(src), "\n")
// Remove old errors.
- for i, ln := range lines {
- pos := strings.Index(ln, " // ERROR ")
- if pos >= 0 {
- lines[i] = ln[:pos]
- }
+ for i := range lines {
+ lines[i], _, _ = strings.Cut(lines[i], " // ERROR ")
}
// Parse new errors.
errors := make(map[int]map[string]bool)
tmpRe := regexp.MustCompile(`autotmp_[0-9]+`)
for _, errStr := range splitOutput(out, false) {
- colon1 := strings.Index(errStr, ":")
- if colon1 < 0 || errStr[:colon1] != file {
+ errFile, rest, ok := strings.Cut(errStr, ":")
+ if !ok || errFile != file {
continue
}
- colon2 := strings.Index(errStr[colon1+1:], ":")
- if colon2 < 0 {
+ lineStr, msg, ok := strings.Cut(rest, ":")
+ if !ok {
continue
}
- colon2 += colon1 + 1
- line, err := strconv.Atoi(errStr[colon1+1 : colon2])
+ line, err := strconv.Atoi(lineStr)
line--
if err != nil || line < 0 || line >= len(lines) {
continue
}
- msg := errStr[colon2+2:]
msg = strings.Replace(msg, file, base, -1) // normalize file mentions in error itself
msg = strings.TrimLeft(msg, " \t")
for _, r := range []string{`\`, `*`, `+`, `?`, `[`, `]`, `(`, `)`} {
@@ -1585,7 +1747,7 @@
// are the supported variants.
archVariants = map[string][]string{
"386": {"GO386", "sse2", "softfloat"},
- "amd64": {},
+ "amd64": {"GOAMD64", "v1", "v2", "v3", "v4"},
"arm": {"GOARM", "5", "6", "7"},
"arm64": {},
"mips": {"GOMIPS", "hardfloat", "softfloat"},
@@ -1594,6 +1756,7 @@
"ppc64le": {"GOPPC64", "power8", "power9"},
"s390x": {},
"wasm": {},
+ "riscv64": {},
}
)
@@ -1941,66 +2104,157 @@
})
}
+// The following is temporary scaffolding to get types2 typechecker
+// up and running against the existing test cases. The explicitly
+// listed files don't pass yet, usually because the error messages
+// are slightly different (this list is not complete). Any errorcheck
+// tests that require output from analysis phases past initial type-
+// checking are also excluded since these phases are not running yet.
+// We can get rid of this code once types2 is fully plugged in.
+
// List of files that the compiler cannot errorcheck with the new typechecker (compiler -G option).
// Temporary scaffolding until we pass all the tests at which point this map can be removed.
-var excluded = map[string]bool{
- "complit1.go": true, // types2 reports extra errors
- "const2.go": true, // types2 not run after syntax errors
- "ddd1.go": true, // issue #42987
- "directive.go": true, // misplaced compiler directive checks
- "float_lit3.go": true, // types2 reports extra errors
- "import1.go": true, // types2 reports extra errors
- "import5.go": true, // issue #42988
- "import6.go": true, // issue #43109
- "initializerr.go": true, // types2 reports extra errors
- "linkname2.go": true, // error reported by noder (not running for types2 errorcheck test)
- "notinheap.go": true, // types2 doesn't report errors about conversions that are invalid due to //go:notinheap
- "shift1.go": true, // issue #42989
- "typecheck.go": true, // invalid function is not causing errors when called
- "writebarrier.go": true, // correct diagnostics, but different lines (probably irgen's fault)
+var types2Failures = setOf(
+ "import1.go", // types2 reports extra errors
+ "import6.go", // issue #43109
+ "initializerr.go", // types2 reports extra errors
+ "notinheap.go", // types2 doesn't report errors about conversions that are invalid due to //go:notinheap
+ "shift1.go", // mostly just different wording, but reports two new errors.
+ "typecheck.go", // invalid function is not causing errors when called
- "fixedbugs/bug176.go": true, // types2 reports all errors (pref: types2)
- "fixedbugs/bug195.go": true, // types2 reports slightly different (but correct) bugs
- "fixedbugs/bug228.go": true, // types2 not run after syntax errors
- "fixedbugs/bug231.go": true, // types2 bug? (same error reported twice)
- "fixedbugs/bug255.go": true, // types2 reports extra errors
- "fixedbugs/bug351.go": true, // types2 reports extra errors
- "fixedbugs/bug374.go": true, // types2 reports extra errors
- "fixedbugs/bug385_32.go": true, // types2 doesn't produce missing error "type .* too large" (32-bit specific)
- "fixedbugs/bug388.go": true, // types2 not run due to syntax errors
- "fixedbugs/bug412.go": true, // types2 produces a follow-on error
+ "fixedbugs/bug176.go", // types2 reports all errors (pref: types2)
+ "fixedbugs/bug195.go", // types2 reports slightly different (but correct) bugs
+ "fixedbugs/bug228.go", // types2 doesn't run when there are syntax errors
+ "fixedbugs/bug231.go", // types2 bug? (same error reported twice)
+ "fixedbugs/bug255.go", // types2 reports extra errors
+ "fixedbugs/bug388.go", // types2 not run due to syntax errors
+ "fixedbugs/bug412.go", // types2 produces a follow-on error
- "fixedbugs/issue11590.go": true, // types2 doesn't report a follow-on error (pref: types2)
- "fixedbugs/issue11610.go": true, // types2 not run after syntax errors
- "fixedbugs/issue11614.go": true, // types2 reports an extra error
- "fixedbugs/issue13415.go": true, // declared but not used conflict
- "fixedbugs/issue14520.go": true, // missing import path error by types2
- "fixedbugs/issue16428.go": true, // types2 reports two instead of one error
- "fixedbugs/issue17038.go": true, // types2 doesn't report a follow-on error (pref: types2)
- "fixedbugs/issue17645.go": true, // multiple errors on same line
- "fixedbugs/issue18331.go": true, // missing error about misuse of //go:noescape (irgen needs code from noder)
- "fixedbugs/issue18393.go": true, // types2 not run after syntax errors
- "fixedbugs/issue19012.go": true, // multiple errors on same line
- "fixedbugs/issue20233.go": true, // types2 reports two instead of one error (pref: compiler)
- "fixedbugs/issue20245.go": true, // types2 reports two instead of one error (pref: compiler)
- "fixedbugs/issue20250.go": true, // correct diagnostics, but different lines (probably irgen's fault)
- "fixedbugs/issue21979.go": true, // types2 doesn't report a follow-on error (pref: types2)
- "fixedbugs/issue23732.go": true, // types2 reports different (but ok) line numbers
- "fixedbugs/issue25958.go": true, // types2 doesn't report a follow-on error (pref: types2)
- "fixedbugs/issue28079b.go": true, // types2 reports follow-on errors
- "fixedbugs/issue28268.go": true, // types2 reports follow-on errors
- "fixedbugs/issue33460.go": true, // types2 reports alternative positions in separate error
- "fixedbugs/issue41575.go": true, // types2 reports alternative positions in separate error
- "fixedbugs/issue42058a.go": true, // types2 doesn't report "channel element type too large"
- "fixedbugs/issue42058b.go": true, // types2 doesn't report "channel element type too large"
- "fixedbugs/issue4232.go": true, // types2 reports (correct) extra errors
- "fixedbugs/issue4452.go": true, // types2 reports (correct) extra errors
- "fixedbugs/issue5609.go": true, // types2 needs a better error message
- "fixedbugs/issue6889.go": true, // types2 can handle this without constant overflow
- "fixedbugs/issue7525.go": true, // types2 reports init cycle error on different line - ok otherwise
- "fixedbugs/issue7525b.go": true, // types2 reports init cycle error on different line - ok otherwise
- "fixedbugs/issue7525c.go": true, // types2 reports init cycle error on different line - ok otherwise
- "fixedbugs/issue7525d.go": true, // types2 reports init cycle error on different line - ok otherwise
- "fixedbugs/issue7525e.go": true, // types2 reports init cycle error on different line - ok otherwise
- "fixedbugs/issue46749.go": true, // types2 reports can not convert error instead of type mismatched
+ "fixedbugs/issue10700.go", // types2 reports ok hint, but does not match regexp
+ "fixedbugs/issue11590.go", // types2 doesn't report a follow-on error (pref: types2)
+ "fixedbugs/issue11610.go", // types2 not run after syntax errors
+ "fixedbugs/issue11614.go", // types2 reports an extra error
+ "fixedbugs/issue14520.go", // missing import path error by types2
+ "fixedbugs/issue17038.go", // types2 doesn't report a follow-on error (pref: types2)
+ "fixedbugs/issue18331.go", // missing error about misuse of //go:noescape (irgen needs code from noder)
+ "fixedbugs/issue18419.go", // types2 reports no field or method member, but should say unexported
+ "fixedbugs/issue19012.go", // multiple errors on same line
+ "fixedbugs/issue20233.go", // types2 reports two instead of one error (pref: compiler)
+ "fixedbugs/issue20245.go", // types2 reports two instead of one error (pref: compiler)
+ "fixedbugs/issue21979.go", // types2 doesn't report a follow-on error (pref: types2)
+ "fixedbugs/issue23732.go", // types2 reports different (but ok) line numbers
+ "fixedbugs/issue25958.go", // types2 doesn't report a follow-on error (pref: types2)
+ "fixedbugs/issue28079b.go", // types2 reports follow-on errors
+ "fixedbugs/issue28268.go", // types2 reports follow-on errors
+ "fixedbugs/issue31053.go", // types2 reports "unknown field" instead of "cannot refer to unexported field"
+ "fixedbugs/issue33460.go", // types2 reports alternative positions in separate error
+ "fixedbugs/issue4232.go", // types2 reports (correct) extra errors
+ "fixedbugs/issue4452.go", // types2 reports (correct) extra errors
+ "fixedbugs/issue4510.go", // types2 reports different (but ok) line numbers
+ "fixedbugs/issue7525b.go", // types2 reports init cycle error on different line - ok otherwise
+ "fixedbugs/issue7525c.go", // types2 reports init cycle error on different line - ok otherwise
+ "fixedbugs/issue7525d.go", // types2 reports init cycle error on different line - ok otherwise
+ "fixedbugs/issue7525e.go", // types2 reports init cycle error on different line - ok otherwise
+ "fixedbugs/issue7525.go", // types2 reports init cycle error on different line - ok otherwise
+)
+
+var types2Failures32Bit = setOf(
+ "printbig.go", // large untyped int passed to print (32-bit)
+ "fixedbugs/bug114.go", // large untyped int passed to println (32-bit)
+ "fixedbugs/issue23305.go", // large untyped int passed to println (32-bit)
+)
+
+var g3Failures = setOf(
+ "typeparam/nested.go", // -G=3 doesn't support function-local types with generics
+)
+
+var unifiedFailures = setOf(
+ "closure3.go", // unified IR numbers closures differently than -d=inlfuncswithclosures
+ "escape4.go", // unified IR can inline f5 and f6; test doesn't expect this
+ "inline.go", // unified IR reports function literal diagnostics on different lines than -d=inlfuncswithclosures
+ "linkname3.go", // unified IR is missing some linkname errors
+
+ "fixedbugs/issue42284.go", // prints "T(0) does not escape", but test expects "a.I(a.T(0)) does not escape"
+ "fixedbugs/issue7921.go", // prints "… escapes to heap", but test expects "string(…) escapes to heap"
+ "typeparam/issue48538.go", // assertion failure, interprets struct key as closure variable
+ "typeparam/issue47631.go", // unified IR can handle local type declarations
+ "fixedbugs/issue42058a.go", // unified IR doesn't report channel element too large
+ "fixedbugs/issue42058b.go", // unified IR doesn't report channel element too large
+ "fixedbugs/issue49767.go", // unified IR doesn't report channel element too large
+ "fixedbugs/issue49814.go", // unified IR doesn't report array type too large
+ "typeparam/issue50002.go", // pure stenciling leads to a static type assertion error
+ "typeparam/typeswitch1.go", // duplicate case failure due to stenciling
+ "typeparam/typeswitch2.go", // duplicate case failure due to stenciling
+ "typeparam/typeswitch3.go", // duplicate case failure due to stenciling
+ "typeparam/typeswitch4.go", // duplicate case failure due to stenciling
+)
+
+func setOf(keys ...string) map[string]bool {
+ m := make(map[string]bool, len(keys))
+ for _, key := range keys {
+ m[key] = true
+ }
+ return m
+}
+
+// splitQuoted splits the string s around each instance of one or more consecutive
+// white space characters while taking into account quotes and escaping, and
+// returns an array of substrings of s or an empty list if s contains only white space.
+// Single quotes and double quotes are recognized to prevent splitting within the
+// quoted region, and are removed from the resulting substrings. If a quote in s
+// isn't closed err will be set and r will have the unclosed argument as the
+// last element. The backslash is used for escaping.
+//
+// For example, the following string:
+//
+// a b:"c d" 'e''f' "g\""
+//
+// Would be parsed as:
+//
+// []string{"a", "b:c d", "ef", `g"`}
+//
+// [copied from src/go/build/build.go]
+func splitQuoted(s string) (r []string, err error) {
+ var args []string
+ arg := make([]rune, len(s))
+ escaped := false
+ quoted := false
+ quote := '\x00'
+ i := 0
+ for _, rune := range s {
+ switch {
+ case escaped:
+ escaped = false
+ case rune == '\\':
+ escaped = true
+ continue
+ case quote != '\x00':
+ if rune == quote {
+ quote = '\x00'
+ continue
+ }
+ case rune == '"' || rune == '\'':
+ quoted = true
+ quote = rune
+ continue
+ case unicode.IsSpace(rune):
+ if quoted || i > 0 {
+ quoted = false
+ args = append(args, string(arg[:i]))
+ i = 0
+ }
+ continue
+ }
+ arg[i] = rune
+ i++
+ }
+ if quoted || i > 0 {
+ args = append(args, string(arg[:i]))
+ }
+ if quote != 0 {
+ err = errors.New("unclosed quote")
+ } else if escaped {
+ err = errors.New("unfinished escaping")
+ }
+ return args, err
}