From: Rob Findley Date: Fri, 23 Oct 2020 13:25:24 +0000 (-0400) Subject: [dev.typeparams] merge master into dev.typeparams X-Git-Tag: go1.17beta1~1473^2~206 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5bfd2964a6;p=gostls13.git [dev.typeparams] merge master into dev.typeparams On top of the merge, the following fixes were applied: + Debug["G"] changed to Debug.G, following golang.org/cl/263539. + issue42058a.go and issue42058b.go were skipped in types2/stdlib_test.go. go/types does not produce errors related to channel element size. Change-Id: I59fc84e12a2d728ef789fdc616f7afe80e451283 --- 5bfd2964a6519c8046b16b41bb9f84ecb6202356 diff --cc src/cmd/compile/internal/gc/go.go index 2fbdf71055,da6b6d6e72..c7627bddcf --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@@ -116,7 -116,15 +116,15 @@@ var decldepth int3 var nolocalimports bool - var Debug [256]int + // gc debug flags + type DebugFlags struct { - P, B, C, E, ++ P, B, C, E, G, + K, L, N, S, + W, e, h, j, + l, m, r, w int + } + + var Debug DebugFlags var debugstr string diff --cc src/cmd/compile/internal/gc/main.go index 21e4757a92,949755a0e2..2a2b6bee01 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@@ -211,19 -211,27 +211,28 @@@ func Main(archInit func(*Arch)) flag.BoolVar(&compiling_runtime, "+", false, "compiling runtime") flag.BoolVar(&compiling_std, "std", false, "compiling standard library") - objabi.Flagcount("%", "debug non-static initializers", &Debug['%']) - objabi.Flagcount("B", "disable bounds checking", &Debug['B']) - objabi.Flagcount("C", "disable printing of columns in error messages", &Debug['C']) // TODO(gri) remove eventually flag.StringVar(&localimport, "D", "", "set relative `path` for local imports") - objabi.Flagcount("E", "debug symbol export", &Debug['E']) - objabi.Flagcount("G", "accept generic code", &Debug['G']) + + objabi.Flagcount("%", "debug non-static initializers", &Debug.P) + objabi.Flagcount("B", "disable bounds checking", &Debug.B) + objabi.Flagcount("C", "disable printing of columns in error messages", &Debug.C) + objabi.Flagcount("E", "debug symbol export", &Debug.E) ++ objabi.Flagcount("G", "accept generic code", &Debug.G) + objabi.Flagcount("K", "debug missing line numbers", &Debug.K) + objabi.Flagcount("L", "show full file names in error messages", &Debug.L) + objabi.Flagcount("N", "disable optimizations", &Debug.N) + objabi.Flagcount("S", "print assembly listing", &Debug.S) + objabi.Flagcount("W", "debug parse tree after type checking", &Debug.W) + objabi.Flagcount("e", "no limit on number of errors reported", &Debug.e) + objabi.Flagcount("h", "halt on error", &Debug.h) + objabi.Flagcount("j", "debug runtime-initialized variables", &Debug.j) + objabi.Flagcount("l", "disable inlining", &Debug.l) + objabi.Flagcount("m", "print optimization decisions", &Debug.m) + objabi.Flagcount("r", "debug generated wrappers", &Debug.r) + objabi.Flagcount("w", "debug type checking", &Debug.w) + objabi.Flagfn1("I", "add `directory` to import search path", addidir) - objabi.Flagcount("K", "debug missing line numbers", &Debug['K']) - objabi.Flagcount("L", "show full file names in error messages", &Debug['L']) - objabi.Flagcount("N", "disable optimizations", &Debug['N']) - objabi.Flagcount("S", "print assembly listing", &Debug['S']) objabi.AddVersionFlag() // -V - objabi.Flagcount("W", "debug parse tree after type checking", &Debug['W']) flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`") flag.StringVar(&buildid, "buildid", "", "record `id` as the build id in the export metadata") flag.IntVar(&nBackendWorkers, "c", 1, "concurrency during compilation, 1 means no concurrency") @@@ -572,16 -573,9 +574,16 @@@ loadsys() timings.Start("fe", "parse") - lines := parseFiles(flag.Args(), Debug['G'] != 0) - lines := parseFiles(flag.Args()) ++ lines := parseFiles(flag.Args(), Debug.G != 0) timings.Stop() timings.AddEvent(int64(lines), "lines") - if Debug['G'] != 0 { ++ if Debug.G != 0 { + // can only parse generic code for now + if nerrors+nsavederrors != 0 { + errorexit() + } + return + } finishUniverse() diff --cc src/cmd/compile/internal/types2/stdlib_test.go index bc8b81998a,0000000000..89e49d84d6 mode 100644,000000..100644 --- a/src/cmd/compile/internal/types2/stdlib_test.go +++ b/src/cmd/compile/internal/types2/stdlib_test.go @@@ -1,320 -1,0 +1,322 @@@ +// UNREVIEWED +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file tests types.Check by using it to +// typecheck the standard library and tests. + +package types2_test + +import ( + "bytes" + "cmd/compile/internal/syntax" + "fmt" + "go/build" + "internal/testenv" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + . "cmd/compile/internal/types2" +) + +var stdLibImporter = defaultImporter() + +func TestStdlib(t *testing.T) { + testenv.MustHaveGoBuild(t) + + pkgCount := 0 + duration := walkPkgDirs(filepath.Join(runtime.GOROOT(), "src"), func(dir string, filenames []string) { + typecheck(t, dir, filenames) + pkgCount++ + }, t.Error) + + if testing.Verbose() { + fmt.Println(pkgCount, "packages typechecked in", duration) + } +} + +// firstComment returns the contents of the first non-empty comment in +// the given file, "skip", or the empty string. No matter the present +// comments, if any of them contains a build tag, the result is always +// "skip". Only comments within the first 4K of the file are considered. +// TODO(gri) should only read until we see "package" token. +func firstComment(filename string) (first string) { + f, err := os.Open(filename) + if err != nil { + return "" + } + defer f.Close() + + // read at most 4KB + var buf [4 << 10]byte + n, _ := f.Read(buf[:]) + src := bytes.NewBuffer(buf[:n]) + + // TODO(gri) we need a better way to terminate CommentsDo + defer func() { + if p := recover(); p != nil { + if s, ok := p.(string); ok { + first = s + } + } + }() + + syntax.CommentsDo(src, func(_, _ uint, text string) { + if text[0] != '/' { + return // not a comment + } + + // extract comment text + if text[1] == '*' { + text = text[:len(text)-2] + } + text = strings.TrimSpace(text[2:]) + + if strings.HasPrefix(text, "+build ") { + panic("skip") + } + if first == "" { + first = text // text may be "" but that's ok + } + // continue as we may still see build tags + }) + + return +} + +func testTestDir(t *testing.T, path string, ignore ...string) { + files, err := ioutil.ReadDir(path) + if err != nil { + t.Fatal(err) + } + + excluded := make(map[string]bool) + for _, filename := range ignore { + excluded[filename] = true + } + + for _, f := range files { + // filter directory contents + if f.IsDir() || !strings.HasSuffix(f.Name(), ".go") || excluded[f.Name()] { + continue + } + + // get per-file instructions + expectErrors := false + filename := filepath.Join(path, f.Name()) + if comment := firstComment(filename); comment != "" { + fields := strings.Fields(comment) + switch fields[0] { + case "skip", "compiledir": + continue // ignore this file + case "errorcheck": + expectErrors = true + for _, arg := range fields[1:] { + if arg == "-0" || arg == "-+" || arg == "-std" { + // Marked explicitly as not expected errors (-0), + // or marked as compiling runtime/stdlib, which is only done + // to trigger runtime/stdlib-only error output. + // In both cases, the code should typecheck. + expectErrors = false + break + } + } + } + } + + // parse and type-check file + if testing.Verbose() { + fmt.Println("\t", filename) + } + file, err := syntax.ParseFile(filename, nil, nil, 0) + if err == nil { + conf := Config{Importer: stdLibImporter} + _, err = conf.Check(filename, []*syntax.File{file}, nil) + } + + if expectErrors { + if err == nil { + t.Errorf("expected errors but found none in %s", filename) + } + } else { + if err != nil { + t.Error(err) + } + } + } +} + +func TestStdTest(t *testing.T) { + testenv.MustHaveGoBuild(t) + + if testing.Short() && testenv.Builder() == "" { + t.Skip("skipping in short mode") + } + + testTestDir(t, filepath.Join(runtime.GOROOT(), "test"), + "cmplxdivide.go", // also needs file cmplxdivide1.go - ignore + "directive.go", // tests compiler rejection of bad directive placement - ignore + ) +} + +func TestStdFixed(t *testing.T) { + testenv.MustHaveGoBuild(t) + + if testing.Short() && testenv.Builder() == "" { + t.Skip("skipping in short mode") + } + + testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "fixedbugs"), + "bug248.go", "bug302.go", "bug369.go", // complex test instructions - ignore + "issue6889.go", // gc-specific test + "issue7746.go", // large constants - consumes too much memory + "issue11362.go", // canonical import path check + "issue16369.go", // go/types handles this correctly - not an issue + "issue18459.go", // go/types doesn't check validity of //go:xxx directives + "issue18882.go", // go/types doesn't check validity of //go:xxx directives + "issue20232.go", // go/types handles larger constants than gc + "issue20529.go", // go/types does not have constraints on stack size + "issue22200.go", // go/types does not have constraints on stack size + "issue22200b.go", // go/types does not have constraints on stack size + "issue25507.go", // go/types does not have constraints on stack size + "issue20780.go", // go/types does not have constraints on stack size + "issue31747.go", // go/types does not have constraints on language level (-lang=go1.12) (see #31793) + "issue34329.go", // go/types does not have constraints on language level (-lang=go1.13) (see #31793) ++ "issue42058a.go", // go/types does not have constraints on channel element size ++ "issue42058b.go", // go/types does not have constraints on channel element size + "bug251.go", // issue #34333 which was exposed with fix for #34151 + ) +} + +func TestStdKen(t *testing.T) { + testenv.MustHaveGoBuild(t) + + testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "ken")) +} + +// Package paths of excluded packages. +var excluded = map[string]bool{ + "builtin": true, +} + +// typecheck typechecks the given package files. +func typecheck(t *testing.T, path string, filenames []string) { + // parse package files + var files []*syntax.File + for _, filename := range filenames { + errh := func(err error) { t.Error(err) } + file, err := syntax.ParseFile(filename, errh, nil, 0) + if err != nil { + return + } + + if testing.Verbose() { + if len(files) == 0 { + fmt.Println("package", file.PkgName.Value) + } + fmt.Println("\t", filename) + } + + files = append(files, file) + } + + // typecheck package files + conf := Config{ + Error: func(err error) { t.Error(err) }, + Importer: stdLibImporter, + } + info := Info{Uses: make(map[*syntax.Name]Object)} + conf.Check(path, files, &info) + + // Perform checks of API invariants. + + // All Objects have a package, except predeclared ones. + errorError := Universe.Lookup("error").Type().Interface().ExplicitMethod(0) // (error).Error + for id, obj := range info.Uses { + predeclared := obj == Universe.Lookup(obj.Name()) || obj == errorError + if predeclared == (obj.Pkg() != nil) { + posn := id.Pos() + if predeclared { + t.Errorf("%s: predeclared object with package: %s", posn, obj) + } else { + t.Errorf("%s: user-defined object without package: %s", posn, obj) + } + } + } +} + +// pkgFilenames returns the list of package filenames for the given directory. +func pkgFilenames(dir string) ([]string, error) { + ctxt := build.Default + ctxt.CgoEnabled = false + pkg, err := ctxt.ImportDir(dir, 0) + if err != nil { + if _, nogo := err.(*build.NoGoError); nogo { + return nil, nil // no *.go files, not an error + } + return nil, err + } + if excluded[pkg.ImportPath] { + return nil, nil + } + var filenames []string + for _, name := range pkg.GoFiles { + filenames = append(filenames, filepath.Join(pkg.Dir, name)) + } + for _, name := range pkg.TestGoFiles { + filenames = append(filenames, filepath.Join(pkg.Dir, name)) + } + return filenames, nil +} + +func walkPkgDirs(dir string, pkgh func(dir string, filenames []string), errh func(args ...interface{})) time.Duration { + w := walker{time.Now(), 10 * time.Millisecond, pkgh, errh} + w.walk(dir) + return time.Since(w.start) +} + +type walker struct { + start time.Time + dmax time.Duration + pkgh func(dir string, filenames []string) + errh func(args ...interface{}) +} + +func (w *walker) walk(dir string) { + // limit run time for short tests + if testing.Short() && time.Since(w.start) >= w.dmax { + return + } + + fis, err := ioutil.ReadDir(dir) + if err != nil { + w.errh(err) + return + } + + // apply pkgh to the files in directory dir + // but ignore files directly under $GOROOT/src (might be temporary test files). + if dir != filepath.Join(runtime.GOROOT(), "src") { + files, err := pkgFilenames(dir) + if err != nil { + w.errh(err) + return + } + if files != nil { + w.pkgh(dir, files) + } + } + + // traverse subdirectories, but don't walk into testdata + for _, fi := range fis { + if fi.IsDir() && fi.Name() != "testdata" { + w.walk(filepath.Join(dir, fi.Name())) + } + } +}