From 656297e1fec9a127ff742df16958ee279ccacec5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 12 Sep 2019 23:22:53 +0000 Subject: [PATCH] libgo: update to Go1.13 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194698 From-SVN: r275691 --- gcc/go/gofrontend/MERGE | 2 +- libgo/MERGE | 2 +- libgo/Makefile.am | 1 + libgo/Makefile.in | 8 +- libgo/VERSION | 2 +- libgo/check-packages.txt | 1 - libgo/go/cmd/cgo/gcc.go | 8 +- libgo/go/cmd/cgo/out.go | 31 +- libgo/go/cmd/go/alldocs.go | 75 +- libgo/go/cmd/go/go_test.go | 6 + libgo/go/cmd/go/internal/cache/cache.go | 27 +- libgo/go/cmd/go/internal/cfg/cfg.go | 55 +- libgo/go/cmd/go/internal/get/vcs.go | 10 +- libgo/go/cmd/go/internal/help/help.go | 2 +- libgo/go/cmd/go/internal/help/helpdoc.go | 3 + libgo/go/cmd/go/internal/list/list.go | 4 +- libgo/go/cmd/go/internal/load/pkg.go | 12 +- libgo/go/cmd/go/internal/load/test.go | 43 +- libgo/go/cmd/go/internal/modcmd/download.go | 39 +- .../cmd/go/internal/modfetch/codehost/vcs.go | 4 +- libgo/go/cmd/go/internal/modfetch/coderepo.go | 75 +- .../cmd/go/internal/modfetch/coderepo_test.go | 97 ++- libgo/go/cmd/go/internal/modfetch/fetch.go | 8 +- libgo/go/cmd/go/internal/modfetch/proxy.go | 4 +- libgo/go/cmd/go/internal/modfetch/repo.go | 2 +- libgo/go/cmd/go/internal/modfetch/sumdb.go | 18 +- libgo/go/cmd/go/internal/modget/get.go | 120 +++- libgo/go/cmd/go/internal/modload/build.go | 2 +- libgo/go/cmd/go/internal/modload/help.go | 25 +- libgo/go/cmd/go/internal/modload/import.go | 7 + libgo/go/cmd/go/internal/modload/list.go | 35 +- libgo/go/cmd/go/internal/modload/load.go | 80 ++- libgo/go/cmd/go/internal/modload/query.go | 73 +- .../go/cmd/go/internal/modload/query_test.go | 30 +- libgo/go/cmd/go/internal/mvs/mvs.go | 25 +- libgo/go/cmd/go/internal/mvs/mvs_test.go | 36 +- libgo/go/cmd/go/internal/test/test.go | 19 +- libgo/go/cmd/go/internal/version/exe.go | 13 +- libgo/go/cmd/go/internal/work/build.go | 4 +- libgo/go/cmd/go/internal/work/buildid.go | 5 +- libgo/go/cmd/go/internal/work/exec.go | 9 - libgo/go/cmd/go/testdata/flag_test.go | 9 +- .../mod/example.com_badchain_c_v1.1.0.txt | 2 +- .../go/testdata/script/build_cache_output.txt | 7 +- .../go/testdata/script/cmd_import_error.txt | 16 + libgo/go/cmd/go/testdata/script/mod_doc.txt | 27 +- libgo/go/cmd/go/testdata/script/mod_dot.txt | 36 + .../cmd/go/testdata/script/mod_download.txt | 14 +- .../testdata/script/mod_download_latest.txt | 20 + .../go/testdata/script/mod_fs_patterns.txt | 4 +- .../go/testdata/script/mod_get_fallback.txt | 10 + .../cmd/go/testdata/script/mod_get_main.txt | 8 +- .../go/testdata/script/mod_get_newcycle.txt | 2 + .../go/testdata/script/mod_get_patterns.txt | 4 +- .../go/cmd/go/testdata/script/mod_get_svn.txt | 13 +- .../script/mod_get_upgrade_pseudo.txt | 38 +- .../go/testdata/script/mod_gobuild_import.txt | 20 +- .../cmd/go/testdata/script/mod_indirect.txt | 81 +++ .../go/testdata/script/mod_indirect_main.txt | 65 ++ .../go/testdata/script/mod_indirect_tidy.txt | 60 ++ .../testdata/script/mod_invalid_version.txt | 31 +- libgo/go/cmd/go/testdata/script/mod_list.txt | 8 +- .../script/mod_list_compiled_concurrent.txt | 41 ++ .../cmd/go/testdata/script/mod_list_dir.txt | 5 +- .../go/testdata/script/mod_list_direct.txt | 24 + .../testdata/script/mod_list_replace_dir.txt | 2 +- .../go/testdata/script/mod_list_upgrade.txt | 20 + .../go/testdata/script/mod_load_badchain.txt | 20 +- libgo/go/cmd/go/testdata/script/mod_query.txt | 2 +- .../go/testdata/script/mod_query_empty.txt | 21 + libgo/go/cmd/go/testdata/script/mod_sumdb.txt | 4 +- .../go/testdata/script/mod_sumdb_cache.txt | 2 +- .../testdata/script/mod_sumdb_file_path.txt | 14 +- .../go/testdata/script/mod_sumdb_golang.txt | 20 +- .../go/testdata/script/mod_sumdb_proxy.txt | 10 +- .../go/testdata/script/mod_test_cached.txt | 77 ++ .../cmd/go/testdata/script/mod_tidy_error.txt | 39 ++ .../go/cmd/go/testdata/script/mod_vendor.txt | 6 - .../script/test_go111module_cache.txt | 15 + libgo/go/cmd/go/testdata/script/test_init.txt | 86 --- libgo/go/cmd/go/testdata/script/version.txt | 7 + .../testdata/standalone_testmain_flag_test.go | 29 + libgo/go/cmd/gofmt/testdata/go2numbers.golden | 186 +++++ libgo/go/cmd/gofmt/testdata/go2numbers.input | 186 +++++ libgo/go/cmd/gofmt/testdata/import.golden | 5 + libgo/go/cmd/gofmt/testdata/import.input | 3 + libgo/go/cmd/gofmt/testdata/rewrite9.golden | 11 + libgo/go/cmd/gofmt/testdata/rewrite9.input | 11 + libgo/go/cmd/gofmt/testdata/typealias.golden | 24 + libgo/go/cmd/gofmt/testdata/typealias.input | 24 + libgo/go/cmd/internal/objabi/flag.go | 10 +- libgo/go/context/context.go | 4 - libgo/go/context/context_test.go | 5 - libgo/go/crypto/rsa/rsa.go | 2 +- libgo/go/crypto/tls/common.go | 9 +- libgo/go/crypto/tls/handshake_server_test.go | 14 + libgo/go/crypto/tls/handshake_test.go | 75 +- libgo/go/crypto/tls/tls_test.go | 44 -- libgo/go/debug/elf/file.go | 40 +- libgo/go/debug/elf/symbols_test.go | 4 + libgo/go/encoding/csv/writer.go | 2 +- libgo/go/encoding/json/decode.go | 68 +- libgo/go/encoding/json/decode_test.go | 2 + libgo/go/encoding/json/encode.go | 6 +- libgo/go/encoding/json/fuzz.go | 2 +- libgo/go/encoding/json/indent.go | 3 - libgo/go/encoding/json/stream_test.go | 26 + libgo/go/errors/errors.go | 49 ++ libgo/go/errors/wrap.go | 6 + libgo/go/expvar/expvar.go | 2 +- libgo/go/fmt/errors.go | 2 +- libgo/go/fmt/scan.go | 2 +- libgo/go/go/ast/import.go | 81 +-- libgo/go/go/build/build.go | 36 +- libgo/go/go/build/deps_test.go | 5 +- libgo/go/go/build/doc.go | 9 +- libgo/go/go/doc/testdata/issue10858.go | 102 --- libgo/go/go/importer/importer.go | 18 +- libgo/go/go/parser/parser.go | 15 +- libgo/go/go/types/scope.go | 4 +- libgo/go/go/types/typestring.go | 2 +- .../go/golang.org/x/net/route/zsys_darwin.go | 2 +- .../golang.org/x/net/route/zsys_dragonfly.go | 2 +- .../x/net/route/zsys_freebsd_386.go | 2 +- .../x/net/route/zsys_freebsd_amd64.go | 2 +- .../x/net/route/zsys_freebsd_arm.go | 2 +- .../go/golang.org/x/net/route/zsys_netbsd.go | 2 +- .../go/golang.org/x/net/route/zsys_openbsd.go | 2 +- libgo/go/internal/cfg/cfg.go | 62 ++ libgo/go/internal/oserror/errors.go | 46 -- libgo/go/internal/oserror/errors_test.go | 63 -- libgo/go/internal/poll/fd.go | 5 - libgo/go/internal/testenv/testenv.go | 7 + libgo/go/net/cgo_unix.go | 11 - libgo/go/net/http/example_test.go | 2 +- libgo/go/net/http/export_test.go | 28 +- libgo/go/net/http/h2_bundle.go | 56 +- libgo/go/net/http/header.go | 6 +- libgo/go/net/http/header_test.go | 8 + libgo/go/net/http/httputil/reverseproxy.go | 3 + .../go/net/http/httputil/reverseproxy_test.go | 20 + libgo/go/net/http/request.go | 6 +- libgo/go/net/http/response.go | 2 +- libgo/go/net/http/serve_test.go | 23 +- libgo/go/net/http/server.go | 8 +- libgo/go/net/http/socks_bundle.go | 2 +- libgo/go/net/http/transport.go | 656 +++++++++++------- libgo/go/net/http/transport_test.go | 206 +++++- libgo/go/net/ip.go | 4 +- libgo/go/net/mail/message.go | 2 +- libgo/go/net/net.go | 27 +- libgo/go/net/net_test.go | 3 + libgo/go/net/pipe.go | 5 - libgo/go/net/timeout_test.go | 52 +- libgo/go/net/url/url.go | 75 +- libgo/go/net/url/url_test.go | 82 ++- libgo/go/os/dir.go | 5 +- libgo/go/os/error.go | 7 +- libgo/go/os/error_errno.go | 11 + libgo/go/os/error_plan9.go | 9 + libgo/go/os/error_test.go | 10 + libgo/go/os/file.go | 4 + libgo/go/os/os_test.go | 2 + libgo/go/os/removeall_at.go | 2 +- libgo/go/os/signal/signal_cgo_test.go | 11 - libgo/go/path/path_test.go | 2 +- libgo/go/reflect/all_test.go | 21 + libgo/go/runtime/cpuprof.go | 27 +- libgo/go/runtime/export_test.go | 34 + libgo/go/runtime/malloc.go | 53 +- libgo/go/runtime/mcache.go | 2 +- libgo/go/runtime/mgcscavenge.go | 8 +- libgo/go/runtime/mheap.go | 18 +- libgo/go/runtime/panic.go | 11 + libgo/go/runtime/pprof/runtime.go | 2 + libgo/go/runtime/proc.go | 7 - libgo/go/runtime/proc_test.go | 4 + libgo/go/runtime/sigqueue.go | 12 + libgo/go/runtime/sigqueue_note.go | 25 + libgo/go/strconv/atof.go | 2 +- libgo/go/strconv/atoi.go | 3 +- libgo/go/strings/example_test.go | 11 +- libgo/go/strings/replace.go | 3 +- libgo/go/strings/strings.go | 7 +- libgo/go/sync/export_test.go | 6 +- libgo/go/sync/once.go | 14 + libgo/go/sync/pool_test.go | 27 +- libgo/go/syscall/exec_bsd.go | 40 +- libgo/go/syscall/exec_darwin.go | 32 +- libgo/go/syscall/exec_linux.go | 32 +- libgo/go/syscall/syscall_errno.go | 4 - libgo/go/syscall/syscall_freebsd.go | 12 +- libgo/go/syscall/syscall_js.go | 4 - libgo/go/testing/testing.go | 5 - libgo/go/text/scanner/scanner.go | 30 +- libgo/go/text/scanner/scanner_test.go | 3 +- libgo/go/time/sleep.go | 9 +- libgo/go/time/time.go | 33 +- libgo/go/time/time_test.go | 9 +- libgo/libgo-packages.txt | 1 + libgo/misc/cgo/errors/errors_test.go | 1 + libgo/misc/cgo/errors/ptr_test.go | 82 ++- libgo/misc/cgo/errors/testdata/issue33061.go | 17 + libgo/misc/cgo/testshared/shared_test.go | 7 + .../testdata/issue30768/issue30768lib/lib.go | 11 + .../testshared/testdata/issue30768/x_test.go | 22 + 206 files changed, 3544 insertions(+), 1694 deletions(-) create mode 100644 libgo/go/cmd/go/testdata/script/cmd_import_error.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_dot.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_download_latest.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_get_fallback.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_indirect.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_indirect_main.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_indirect_tidy.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_list_compiled_concurrent.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_list_direct.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_test_cached.txt create mode 100644 libgo/go/cmd/go/testdata/script/mod_tidy_error.txt create mode 100644 libgo/go/cmd/go/testdata/script/test_go111module_cache.txt delete mode 100644 libgo/go/cmd/go/testdata/script/test_init.txt create mode 100644 libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go create mode 100644 libgo/go/cmd/gofmt/testdata/go2numbers.golden create mode 100644 libgo/go/cmd/gofmt/testdata/go2numbers.input create mode 100644 libgo/go/cmd/gofmt/testdata/rewrite9.golden create mode 100644 libgo/go/cmd/gofmt/testdata/rewrite9.input create mode 100644 libgo/go/cmd/gofmt/testdata/typealias.golden create mode 100644 libgo/go/cmd/gofmt/testdata/typealias.input delete mode 100644 libgo/go/go/doc/testdata/issue10858.go create mode 100644 libgo/go/internal/cfg/cfg.go delete mode 100644 libgo/go/internal/oserror/errors_test.go create mode 100644 libgo/go/os/error_errno.go create mode 100644 libgo/go/os/error_plan9.go create mode 100644 libgo/go/runtime/sigqueue_note.go create mode 100644 libgo/misc/cgo/errors/testdata/issue33061.go create mode 100644 libgo/misc/cgo/testshared/testdata/issue30768/issue30768lib/lib.go create mode 100644 libgo/misc/cgo/testshared/testdata/issue30768/x_test.go diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 8098eb047da..f950ecdb0e3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -0950e905939f88c1421f8667ac4dc9e14528471c +ceb1e4f5614b4772eed44f9cf57780e52f44753e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/MERGE b/libgo/MERGE index 533c99da984..0be22963bb8 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -60f14fddfee107dedd76c0be6b422a3d8ccc841a +cc8838d645b2b7026c1f3aaceb011775c5ca3a08 The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index b46f920d8ee..1192b449781 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -401,6 +401,7 @@ toolexeclibgounicode_DATA = \ # Force them to be built. noinst_DATA = \ golang.org/x/net/nettest.gox \ + internal/cfg.gox \ internal/testenv.gox \ internal/trace.gox \ net/internal/socktest.gox \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index eeec5fc7c98..89cccaccdf9 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -856,10 +856,10 @@ toolexeclibgounicode_DATA = \ # Some packages are only needed for tests, so unlike the other # internal packages nothing will explicitly depend on them. # Force them to be built. -noinst_DATA = golang.org/x/net/nettest.gox internal/testenv.gox \ - internal/trace.gox net/internal/socktest.gox \ - os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \ - zdefaultcc.go +noinst_DATA = golang.org/x/net/nettest.gox internal/cfg.gox \ + internal/testenv.gox internal/trace.gox \ + net/internal/socktest.gox os/signal/internal/pty.gox \ + runtime/pprof/internal/profile.gox zdefaultcc.go @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c runtime_files = \ diff --git a/libgo/VERSION b/libgo/VERSION index a49377394fe..e0f726521a4 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.13beta1 +go1.13 diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt index a13624303dd..156a2bd4593 100644 --- a/libgo/check-packages.txt +++ b/libgo/check-packages.txt @@ -106,7 +106,6 @@ image/png index/suffixarray internal/cpu internal/fmtsort -internal/oserror internal/poll internal/reflectlite internal/singleflight diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go index 70be6dc9a92..526d4c2bddf 100644 --- a/libgo/go/cmd/cgo/gcc.go +++ b/libgo/go/cmd/cgo/gcc.go @@ -811,10 +811,10 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) { params := name.FuncType.Params args := call.Call.Args - // Avoid a crash if the number of arguments is - // less than the number of parameters. + // Avoid a crash if the number of arguments doesn't match + // the number of parameters. // This will be caught when the generated file is compiled. - if len(args) < len(params) { + if len(args) != len(params) { return "", false } @@ -1257,6 +1257,8 @@ func (p *Package) isType(t ast.Expr) bool { if strings.HasPrefix(t.Name, "_Ctype_") { return true } + case *ast.ParenExpr: + return p.isType(t.X) case *ast.StarExpr: return p.isType(t.X) case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index 77e9108dd23..7282933e3c5 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -273,6 +273,35 @@ func (p *Package) writeDefs() { } } +// elfImportedSymbols is like elf.File.ImportedSymbols, but it +// includes weak symbols. +// +// A bug in some versions of LLD (at least LLD 8) cause it to emit +// several pthreads symbols as weak, but we need to import those. See +// issue #31912 or https://bugs.llvm.org/show_bug.cgi?id=42442. +// +// When doing external linking, we hand everything off to the external +// linker, which will create its own dynamic symbol tables. For +// internal linking, this may turn weak imports into strong imports, +// which could cause dynamic linking to fail if a symbol really isn't +// defined. However, the standard library depends on everything it +// imports, and this is the primary use of dynamic symbol tables with +// internal linking. +func elfImportedSymbols(f *elf.File) []elf.ImportedSymbol { + syms, _ := f.DynamicSymbols() + var imports []elf.ImportedSymbol + for _, s := range syms { + if (elf.ST_BIND(s.Info) == elf.STB_GLOBAL || elf.ST_BIND(s.Info) == elf.STB_WEAK) && s.Section == elf.SHN_UNDEF { + imports = append(imports, elf.ImportedSymbol{ + Name: s.Name, + Library: s.Library, + Version: s.Version, + }) + } + } + return imports +} + func dynimport(obj string) { stdout := os.Stdout if *dynout != "" { @@ -295,7 +324,7 @@ func dynimport(obj string) { } } } - sym, _ := f.ImportedSymbols() + sym := elfImportedSymbols(f) for _, s := range sym { targ := s.Name if s.Version != "" { diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go index fa60fb63b57..ebbead5d316 100644 --- a/libgo/go/cmd/go/alldocs.go +++ b/libgo/go/cmd/go/alldocs.go @@ -78,6 +78,8 @@ // If the arguments to build are a list of .go files from a single directory, // build treats them as a list of source files specifying a single package. // +// When compiling packages, build ignores files that end in '_test.go'. +// // When compiling a single main package, build writes // the resulting executable to an output file named after // the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe') @@ -88,8 +90,6 @@ // build compiles the packages but discards the resulting object, // serving only as a check that the packages can be built. // -// When compiling packages, build ignores files that end in '_test.go'. -// // The -o flag forces build to write the resulting executable or object // to the named output file or directory, instead of the default behavior described // in the last two paragraphs. If the named output is a directory that exists, @@ -566,17 +566,27 @@ // The first step is to resolve which dependencies to add. // // For each named package or package pattern, get must decide which version of -// the corresponding module to use. By default, get chooses the latest tagged +// the corresponding module to use. By default, get looks up the latest tagged // release version, such as v0.4.5 or v1.2.3. If there are no tagged release -// versions, get chooses the latest tagged pre-release version, such as -// v0.0.1-pre1. If there are no tagged versions at all, get chooses the latest -// known commit. +// versions, get looks up the latest tagged pre-release version, such as +// v0.0.1-pre1. If there are no tagged versions at all, get looks up the latest +// known commit. If the module is not already required at a later version +// (for example, a pre-release newer than the latest release), get will use +// the version it looked up. Otherwise, get will use the currently +// required version. // // This default version selection can be overridden by adding an @version // suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'. +// The version may be a prefix: @v1 denotes the latest available version starting +// with v1. See 'go help modules' under the heading 'Module queries' for the +// full query syntax. +// // For modules stored in source control repositories, the version suffix can // also be a commit hash, branch identifier, or other syntax known to the -// source control system, as in 'go get golang.org/x/text@master'. +// source control system, as in 'go get golang.org/x/text@master'. Note that +// branches with names that overlap with other module query syntax cannot be +// selected explicitly. For example, the suffix @v2 means the latest version +// starting with v2, not the branch named v2. // // If a module under consideration is already a dependency of the current // development module, then get will update the required version. @@ -586,12 +596,14 @@ // depending on it as needed. // // The version suffix @latest explicitly requests the latest minor release of the -// given path. The suffix @patch requests the latest patch release: if the path -// is already in the build list, the selected version will have the same minor -// version. If the path is not already in the build list, @patch is equivalent -// to @latest. Neither @latest nor @patch will cause 'go get' to downgrade a module -// in the build list if it is required at a newer pre-release version that is -// newer than the latest released version. +// module named by the given path. The suffix @upgrade is like @latest but +// will not downgrade a module if it is already required at a revision or +// pre-release version newer than the latest released version. The suffix +// @patch requests the latest patch release: the latest released version +// with the same major and minor version numbers as the currently required +// version. Like @upgrade, @patch will not downgrade a module already required +// at a newer version. If the path is not already required, @upgrade and @patch +// are equivalent to @latest. // // Although get defaults to using the latest version of the module containing // a named package, it does not use the latest version of that module's @@ -1006,6 +1018,7 @@ // Dir string // absolute path to cached source root directory // Sum string // checksum for path, version (as in go.sum) // GoModSum string // checksum for go.mod (as in go.sum) +// Latest bool // would @latest resolve to this version? // } // // See 'go help modules' for more about module queries. @@ -1562,6 +1575,9 @@ // GOCACHE // The directory where the go command will store cached // information for reuse in future builds. +// GODEBUG +// Enable various debugging facilities. See 'go doc runtime' +// for details. // GOENV // The location of the Go environment configuration file. // Cannot be set using 'go env -w'. @@ -2496,12 +2512,25 @@ // The string "latest" matches the latest available tagged version, // or else the underlying source repository's latest untagged revision. // -// A revision identifier for the underlying source repository, -// such as a commit hash prefix, revision tag, or branch name, -// selects that specific code revision. If the revision is -// also tagged with a semantic version, the query evaluates to -// that semantic version. Otherwise the query evaluates to a -// pseudo-version for the commit. +// The string "upgrade" is like "latest", but if the module is +// currently required at a later version than the version "latest" +// would select (for example, a newer pre-release version), "upgrade" +// will select the later version instead. +// +// The string "patch" matches the latest available tagged version +// of a module with the same major and minor version numbers as the +// currently required version. If no version is currently required, +// "patch" is equivalent to "latest". +// +// A revision identifier for the underlying source repository, such as +// a commit hash prefix, revision tag, or branch name, selects that +// specific code revision. If the revision is also tagged with a +// semantic version, the query evaluates to that semantic version. +// Otherwise the query evaluates to a pseudo-version for the commit. +// Note that branches and tags with names that are matched by other +// query syntax cannot be selected this way. For example, the query +// "v2" means the latest version starting with "v2", not the branch +// named "v2". // // All queries prefer release versions to pre-release versions. // For example, " 0 { - helpSuccess = " " + strings.Join(args[:i], " ") + helpSuccess += " " + strings.Join(args[:i], " ") } fmt.Fprintf(os.Stderr, "go help %s: unknown help topic. Run '%s'.\n", strings.Join(args, " "), helpSuccess) base.SetExitStatus(2) // failed at 'go help cmd' diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go index c2b5fb4b830..dfb89d4910b 100644 --- a/libgo/go/cmd/go/internal/help/helpdoc.go +++ b/libgo/go/cmd/go/internal/help/helpdoc.go @@ -493,6 +493,9 @@ General-purpose environment variables: GOCACHE The directory where the go command will store cached information for reuse in future builds. + GODEBUG + Enable various debugging facilities. See 'go doc runtime' + for details. GOENV The location of the Go environment configuration file. Cannot be set using 'go env -w'. diff --git a/libgo/go/cmd/go/internal/list/list.go b/libgo/go/cmd/go/internal/list/list.go index e7e78e7c597..a5f1abe64ae 100644 --- a/libgo/go/cmd/go/internal/list/list.go +++ b/libgo/go/cmd/go/internal/list/list.go @@ -390,7 +390,7 @@ func runList(cmd *base.Command, args []string) { if !*listE { for _, m := range mods { if m.Error != nil { - base.Errorf("go list -m %s: %v", m.Path, m.Error.Err) + base.Errorf("go list -m: %v", m.Error.Err) } } base.ExitIfErrors() @@ -459,7 +459,7 @@ func runList(cmd *base.Command, args []string) { } if pmain != nil { pkgs = append(pkgs, pmain) - data := pmain.Internal.TestmainGo + data := *pmain.Internal.TestmainGo h := cache.NewHash("testmain") h.Write([]byte("testmain\n")) h.Write(data) diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index 958356070c5..a50450ee054 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -64,7 +64,7 @@ type PackagePublic struct { Doc string `json:",omitempty"` // package documentation string Target string `json:",omitempty"` // installed target for this package (may be executable) Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared) - Root string `json:",omitempty"` // Go root or Go path dir containing this package + Root string `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory ForTest string `json:",omitempty"` // package is only for use in named test Export string `json:",omitempty"` // file containing export data (set by go list -export) @@ -177,8 +177,7 @@ type PackageInternal struct { OmitDebug bool // tell linker not to write debug information GobinSubdir bool // install target would be subdir of GOBIN BuildInfo string // add this info to package main - TestinginitGo []byte // content for _testinginit.go - TestmainGo []byte // content for _testmain.go + TestmainGo *[]byte // content for _testmain.go Asmflags []string // -asmflags for this package Gcflags []string // -gcflags for this package @@ -647,9 +646,14 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd buildMode = build.ImportComment } data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode) + if data.p.Root == "" && cfg.ModulesEnabled { + if info := ModPackageModuleInfo(path); info != nil { + data.p.Root = info.Dir + } + } } else if r.err != nil { data.p = new(build.Package) - data.err = fmt.Errorf("unknown import path %q: %v", r.path, r.err) + data.err = r.err } else if cfg.ModulesEnabled && path != "unsafe" { data.p = new(build.Package) data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path) diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go index c247d56c812..afff5deaaa9 100644 --- a/libgo/go/cmd/go/internal/load/test.go +++ b/libgo/go/cmd/go/internal/load/test.go @@ -102,7 +102,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * var stk ImportStack stk.Push(p.ImportPath + " (test)") rawTestImports := str.StringList(p.TestImports) - var ptestImportsTesting, pxtestImportsTesting bool for i, path := range p.TestImports { p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport) if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath { @@ -117,9 +116,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * } p.TestImports[i] = p1.ImportPath imports = append(imports, p1) - if path == "testing" { - ptestImportsTesting = true - } } stk.Pop() stk.Push(p.ImportPath + "_test") @@ -133,9 +129,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ximports = append(ximports, p1) } p.XTestImports[i] = p1.ImportPath - if path == "testing" { - pxtestImportsTesting = true - } } stk.Pop() @@ -145,9 +138,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * *ptest = *p ptest.Error = ptestErr ptest.ForTest = p.ImportPath - if ptestImportsTesting { - ptest.Internal.TestinginitGo = formatTestinginit(p) - } ptest.GoFiles = nil ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...) @@ -212,9 +202,6 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * Gccgoflags: p.Internal.Gccgoflags, }, } - if pxtestImportsTesting { - pxtest.Internal.TestinginitGo = formatTestinginit(pxtest) - } if pxtestNeedsPtest { pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest) } @@ -337,7 +324,9 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * if err != nil && pmain.Error == nil { pmain.Error = &PackageError{Err: err.Error()} } - pmain.Internal.TestmainGo = data + if data != nil { + pmain.Internal.TestmainGo = &data + } return pmain, ptest, pxtest } @@ -485,15 +474,6 @@ func loadTestFuncs(ptest *Package) (*testFuncs, error) { return t, err } -// formatTestinginit returns the content of the _testinginit.go file for p. -func formatTestinginit(p *Package) []byte { - var buf bytes.Buffer - if err := testinginitTmpl.Execute(&buf, p); err != nil { - panic("testinginit template execution failed") // shouldn't be possible - } - return buf.Bytes() -} - // formatTestmain returns the content of the _testmain.go file for t. func formatTestmain(t *testFuncs) ([]byte, error) { var buf bytes.Buffer @@ -623,23 +603,6 @@ func checkTestFunc(fn *ast.FuncDecl, arg string) error { return nil } -var testinginitTmpl = lazytemplate.New("init", ` -package {{.Name}} - -import _go_testing "testing" - -{{/* -Call testing.Init before any other user initialization code runs. -(This file is passed to the compiler first.) -This provides the illusion of the old behavior where testing flags -were registered as part of the testing package's initialization. -*/}} -var _ = func() bool { - _go_testing.Init() - return true -}() -`) - var testmainTmpl = lazytemplate.New("main", ` // Code generated by 'go test'. DO NOT EDIT. diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go index 71b660d6fde..60d0d5b6e2b 100644 --- a/libgo/go/cmd/go/internal/modcmd/download.go +++ b/libgo/go/cmd/go/internal/modcmd/download.go @@ -43,6 +43,7 @@ corresponding to this Go struct: Dir string // absolute path to cached source root directory Sum string // checksum for path, version (as in go.sum) GoModSum string // checksum for go.mod (as in go.sum) + Latest bool // would @latest resolve to this version? } See 'go help modules' for more about module queries. @@ -65,6 +66,7 @@ type moduleJSON struct { Dir string `json:",omitempty"` Sum string `json:",omitempty"` GoModSum string `json:",omitempty"` + Latest bool `json:",omitempty"` } func runDownload(cmd *base.Command, args []string) { @@ -87,7 +89,8 @@ func runDownload(cmd *base.Command, args []string) { if info.Replace != nil { info = info.Replace } - if info.Version == "" { + if info.Version == "" && info.Error == nil { + // main module continue } m := &moduleJSON{ @@ -95,9 +98,38 @@ func runDownload(cmd *base.Command, args []string) { Version: info.Version, } mods = append(mods, m) + if info.Error != nil { + m.Error = info.Error.Err + continue + } work.Add(m) } + latest := map[string]string{} // path → version + if *downloadJSON { + // We need to populate the Latest field, but if the main module depends on a + // version newer than latest — or if the version requested on the command + // line is itself newer than latest — that's not trivial to determine from + // the info returned by ListModules. Instead, we issue a separate + // ListModules request for "latest", which should be inexpensive relative to + // downloading the modules. + var latestArgs []string + for _, m := range mods { + if m.Error != "" { + continue + } + latestArgs = append(latestArgs, m.Path+"@latest") + } + + if len(latestArgs) > 0 { + for _, info := range modload.ListModules(latestArgs, listU, listVersions) { + if info.Version != "" { + latest[info.Path] = info.Version + } + } + } + } + work.Do(10, func(item interface{}) { m := item.(*moduleJSON) var err error @@ -128,6 +160,9 @@ func runDownload(cmd *base.Command, args []string) { m.Error = err.Error() return } + if latest[m.Path] == m.Version { + m.Latest = true + } }) if *downloadJSON { @@ -144,7 +179,7 @@ func runDownload(cmd *base.Command, args []string) { } else { for _, m := range mods { if m.Error != "" { - base.Errorf("%s@%s: %s\n", m.Path, m.Version, m.Error) + base.Errorf("%s", m.Error) } } base.ExitIfErrors() diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go b/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go index b1845f5c650..48238f176c6 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go @@ -341,7 +341,9 @@ func (r *vcsRepo) Stat(rev string) (*RevInfo, error) { } func (r *vcsRepo) fetch() { - _, r.fetchErr = Run(r.dir, r.cmd.fetch) + if len(r.cmd.fetch) > 0 { + _, r.fetchErr = Run(r.dir, r.cmd.fetch) + } } func (r *vcsRepo) statLocal(rev string) (*RevInfo, error) { diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo.go b/libgo/go/cmd/go/internal/modfetch/coderepo.go index 267b76349dd..f15ce67d460 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo.go @@ -31,7 +31,7 @@ type codeRepo struct { codeRoot string // codeDir is the directory (relative to root) at which we expect to find the module. // If pathMajor is non-empty and codeRoot is not the full modPath, - // then we look in both codeDir and codeDir+modPath + // then we look in both codeDir and codeDir/pathMajor[1:]. codeDir string // pathMajor is the suffix of modPath that indicates its major version, @@ -192,7 +192,13 @@ func (r *codeRepo) Stat(rev string) (*RevInfo, error) { codeRev := r.revToRev(rev) info, err := r.code.Stat(codeRev) if err != nil { - return nil, err + return nil, &module.ModuleError{ + Path: r.modPath, + Err: &module.InvalidVersionError{ + Version: rev, + Err: err, + }, + } } return r.convert(info, rev) } @@ -248,20 +254,25 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e // exist as required by info2.Version and the module path represented by r. checkGoMod := func() (*RevInfo, error) { // If r.codeDir is non-empty, then the go.mod file must exist: the module - // author, not the module consumer, gets to decide how to carve up the repo + // author — not the module consumer, — gets to decide how to carve up the repo // into modules. - if r.codeDir != "" { - _, _, _, err := r.findDir(info2.Version) - if err != nil { - // TODO: It would be nice to return an error like "not a module". - // Right now we return "missing go.mod", which is a little confusing. - return nil, &module.ModuleError{ - Path: r.modPath, - Err: &module.InvalidVersionError{ - Version: info2.Version, - Err: notExistError(err.Error()), - }, - } + // + // Conversely, if the go.mod file exists, the module author — not the module + // consumer — gets to determine the module's path + // + // r.findDir verifies both of these conditions. Execute it now so that + // r.Stat will correctly return a notExistError if the go.mod location or + // declared module path doesn't match. + _, _, _, err := r.findDir(info2.Version) + if err != nil { + // TODO: It would be nice to return an error like "not a module". + // Right now we return "missing go.mod", which is a little confusing. + return nil, &module.ModuleError{ + Path: r.modPath, + Err: &module.InvalidVersionError{ + Version: info2.Version, + Err: notExistError(err.Error()), + }, } } @@ -474,6 +485,11 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string) return fmt.Errorf("does not match version-control timestamp (%s)", info.Time.UTC().Format(time.RFC3339)) } + tagPrefix := "" + if r.codeDir != "" { + tagPrefix = r.codeDir + "/" + } + // A pseudo-version should have a precedence just above its parent revisions, // and no higher. Otherwise, it would be possible for library authors to "pin" // dependency versions (and bypass the usual minimum version selection) by @@ -499,11 +515,26 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string) return fmt.Errorf("major version without preceding tag must be v0, not v1") } return nil - } - - tagPrefix := "" - if r.codeDir != "" { - tagPrefix = r.codeDir + "/" + } else { + for _, tag := range info.Tags { + versionOnly := strings.TrimPrefix(tag, tagPrefix) + if versionOnly == base { + // The base version is canonical, so if the version from the tag is + // literally equal (not just equivalent), then the tag is canonical too. + // + // We allow pseudo-versions to be derived from non-canonical tags on the + // same commit, so that tags like "v1.1.0+some-metadata" resolve as + // close as possible to the canonical version ("v1.1.0") while still + // enforcing a total ordering ("v1.1.1-0.[…]" with a unique suffix). + // + // However, canonical tags already have a total ordering, so there is no + // reason not to use the canonical tag directly, and we know that the + // canonical tag must already exist because the pseudo-version is + // derived from it. In that case, referring to the revision by a + // pseudo-version derived from its own canonical tag is just confusing. + return fmt.Errorf("tag (%s) found on revision %s is already canonical, so should not be replaced with a pseudo-version derived from that tag", tag, rev) + } + } } tags, err := r.code.Tags(tagPrefix + base) @@ -571,6 +602,10 @@ func (r *codeRepo) versionToRev(version string) (rev string, err error) { return r.revToRev(version), nil } +// findDir locates the directory within the repo containing the module. +// +// If r.pathMajor is non-empty, this can be either r.codeDir or — if a go.mod +// file exists — r.codeDir/r.pathMajor[1:]. func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err error) { rev, err = r.versionToRev(version) if err != nil { diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go index 5fc9bc34397..1f2b95bd238 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go @@ -83,6 +83,26 @@ var codeRepoTests = []codeRepoTest{ "pkg/p.go", }, }, + { + vcs: "git", + path: "github.com/rsc/vgotest1", + rev: "v0.0.0-20180219231006-80d85c5d4d17", + version: "v0.0.0-20180219231006-80d85c5d4d17", + name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", + short: "80d85c5d4d17", + time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), + zip: []string{ + "LICENSE", + "README.md", + "pkg/p.go", + }, + }, + { + vcs: "git", + path: "github.com/rsc/vgotest1", + rev: "v0.0.1-0.20180219231006-80d85c5d4d17", + err: `github.com/rsc/vgotest1@v0.0.1-0.20180219231006-80d85c5d4d17: invalid pseudo-version: tag (v0.0.0) found on revision 80d85c5d4d17 is already canonical, so should not be replaced with a pseudo-version derived from that tag`, + }, { vcs: "git", path: "github.com/rsc/vgotest1", @@ -105,7 +125,7 @@ var codeRepoTests = []codeRepoTest{ name: "45f53230a74ad275c7127e117ac46914c8126160", short: "45f53230a74a", time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC), - ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", + err: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", }, { vcs: "git", @@ -136,15 +156,14 @@ var codeRepoTests = []codeRepoTest{ }, }, { - vcs: "git", - path: "github.com/rsc/vgotest1/v2", - rev: "45f53230a", - version: "v2.0.0", - name: "45f53230a74ad275c7127e117ac46914c8126160", - short: "45f53230a74a", - time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC), - gomoderr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", - ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", + vcs: "git", + path: "github.com/rsc/vgotest1/v2", + rev: "45f53230a", + version: "v2.0.0", + name: "45f53230a74ad275c7127e117ac46914c8126160", + short: "45f53230a74a", + time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC), + err: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", }, { vcs: "git", @@ -154,7 +173,7 @@ var codeRepoTests = []codeRepoTest{ name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", short: "80d85c5d4d17", time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), - ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17", + err: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17", }, { vcs: "git", @@ -210,24 +229,24 @@ var codeRepoTests = []codeRepoTest{ gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n", }, { - vcs: "git", - path: "github.com/rsc/vgotest1/v2", - rev: "v2.0.3", - version: "v2.0.3", - name: "f18795870fb14388a21ef3ebc1d75911c8694f31", - short: "f18795870fb1", - time: time.Date(2018, 2, 19, 23, 16, 4, 0, time.UTC), - gomoderr: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3", + vcs: "git", + path: "github.com/rsc/vgotest1/v2", + rev: "v2.0.3", + version: "v2.0.3", + name: "f18795870fb14388a21ef3ebc1d75911c8694f31", + short: "f18795870fb1", + time: time.Date(2018, 2, 19, 23, 16, 4, 0, time.UTC), + err: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3", }, { - vcs: "git", - path: "github.com/rsc/vgotest1/v2", - rev: "v2.0.4", - version: "v2.0.4", - name: "1f863feb76bc7029b78b21c5375644838962f88d", - short: "1f863feb76bc", - time: time.Date(2018, 2, 20, 0, 3, 38, 0, time.UTC), - gomoderr: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4", + vcs: "git", + path: "github.com/rsc/vgotest1/v2", + rev: "v2.0.4", + version: "v2.0.4", + name: "1f863feb76bc7029b78b21c5375644838962f88d", + short: "1f863feb76bc", + time: time.Date(2018, 2, 20, 0, 3, 38, 0, time.UTC), + err: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4", }, { vcs: "git", @@ -504,6 +523,7 @@ func TestCodeRepo(t *testing.T) { tt.name = remap(tt.name, m) tt.short = remap(tt.short, m) tt.rev = remap(tt.rev, m) + tt.err = remap(tt.err, m) tt.gomoderr = remap(tt.gomoderr, m) tt.ziperr = remap(tt.ziperr, m) t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt)) @@ -515,7 +535,7 @@ func TestCodeRepo(t *testing.T) { } var hgmap = map[string]string{ - "github.com/rsc/vgotest1/": "vcs-test.golang.org/hg/vgotest1.hg/", + "github.com/rsc/vgotest1": "vcs-test.golang.org/hg/vgotest1.hg", "f18795870fb14388a21ef3ebc1d75911c8694f31": "a9ad6d1d14eb544f459f446210c7eb3b009807c6", "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9": "f1fc0f22021b638d073d31c752847e7bf385def7", "b769f2de407a4db81af9c5de0a06016d60d2ea09": "92c7eb888b4fac17f1c6bd2e1060a1b881a3b832", @@ -631,15 +651,30 @@ var latestTests = []struct { err: "no commits", }, { - vcs: "git", - path: "github.com/rsc/vgotest1", - version: "v0.0.0-20180219223237-a08abb797a67", + vcs: "git", + path: "github.com/rsc/vgotest1", + err: `github.com/rsc/vgotest1@v0.0.0-20180219223237-a08abb797a67: invalid version: go.mod has post-v0 module path "github.com/vgotest1/v2" at revision a08abb797a67`, + }, + { + vcs: "git", + path: "github.com/rsc/vgotest1/v2", + err: `github.com/rsc/vgotest1/v2@v2.0.0-20180219223237-a08abb797a67: invalid version: github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision a08abb797a67`, }, { vcs: "git", path: "github.com/rsc/vgotest1/subdir", err: "github.com/rsc/vgotest1/subdir@v0.0.0-20180219223237-a08abb797a67: invalid version: missing github.com/rsc/vgotest1/subdir/go.mod at revision a08abb797a67", }, + { + vcs: "git", + path: "vcs-test.golang.org/git/commit-after-tag.git", + version: "v1.0.1-0.20190715211727-b325d8217783", + }, + { + vcs: "git", + path: "vcs-test.golang.org/git/no-tags.git", + version: "v0.0.0-20190715212047-e706ba1d9f6d", + }, { vcs: "mod", path: "swtch.com/testmod", diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go index 74e36cc6fc1..51a56028c4a 100644 --- a/libgo/go/cmd/go/internal/modfetch/fetch.go +++ b/libgo/go/cmd/go/internal/modfetch/fetch.go @@ -701,9 +701,11 @@ to use and optionally its public key and URL, as in: GOSUMDB="sum.golang.org+" GOSUMDB="sum.golang.org+ https://sum.golang.org" -The go command knows the public key of sum.golang.org; use of any other -database requires giving the public key explicitly. The URL defaults to -"https://" followed by the database name. +The go command knows the public key of sum.golang.org, and also that the name +sum.golang.google.cn (available inside mainland China) connects to the +sum.golang.org checksum database; use of any other database requires giving +the public key explicitly. +The URL defaults to "https://" followed by the database name. GOSUMDB defaults to "sum.golang.org", the Go checksum database run by Google. See https://sum.golang.org/privacy for the service's privacy policy. diff --git a/libgo/go/cmd/go/internal/modfetch/proxy.go b/libgo/go/cmd/go/internal/modfetch/proxy.go index 6049ccfd30a..569ef3a57a6 100644 --- a/libgo/go/cmd/go/internal/modfetch/proxy.go +++ b/libgo/go/cmd/go/internal/modfetch/proxy.go @@ -345,7 +345,9 @@ func (p *proxyRepo) Stat(rev string) (*RevInfo, error) { func (p *proxyRepo) Latest() (*RevInfo, error) { data, err := p.getBytes("@latest") if err != nil { - // TODO return err if not 404 + if !errors.Is(err, os.ErrNotExist) { + return nil, p.versionError("", err) + } return p.latest() } info := new(RevInfo) diff --git a/libgo/go/cmd/go/internal/modfetch/repo.go b/libgo/go/cmd/go/internal/modfetch/repo.go index 95351269dbe..be52a8dc11f 100644 --- a/libgo/go/cmd/go/internal/modfetch/repo.go +++ b/libgo/go/cmd/go/internal/modfetch/repo.go @@ -240,7 +240,7 @@ func lookup(proxy, path string) (r Repo, err error) { var ( errModVendor = errors.New("module lookup disabled by -mod=vendor") - errProxyOff = errors.New("module lookup disabled by GOPROXY=off") + errProxyOff = notExistError("module lookup disabled by GOPROXY=off") errNoproxy error = notExistError("disabled by GOPRIVATE/GONOPROXY") errUseProxy error = notExistError("path does not match GOPRIVATE/GONOPROXY") ) diff --git a/libgo/go/cmd/go/internal/modfetch/sumdb.go b/libgo/go/cmd/go/internal/modfetch/sumdb.go index 66a09d32c27..1c24ec273b5 100644 --- a/libgo/go/cmd/go/internal/modfetch/sumdb.go +++ b/libgo/go/cmd/go/internal/modfetch/sumdb.go @@ -60,7 +60,17 @@ func dbDial() (dbName string, db *sumweb.Conn, err error) { // $GOSUMDB can be "key" or "key url", // and the key can be a full verifier key // or a host on our list of known keys. - key := strings.Fields(cfg.GOSUMDB) + + // Special case: sum.golang.google.cn + // is an alias, reachable inside mainland China, + // for sum.golang.org. If there are more + // of these we should add a map like knownGOSUMDB. + gosumdb := cfg.GOSUMDB + if gosumdb == "sum.golang.google.cn" { + gosumdb = "sum.golang.org https://sum.golang.google.cn" + } + + key := strings.Fields(gosumdb) if len(key) >= 1 { if k := knownGOSUMDB[key[0]]; k != "" { key[0] = k @@ -232,10 +242,10 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error { } // ReadCache reads cached lookups or tiles from -// GOPATH/pkg/mod/download/cache/sumdb, +// GOPATH/pkg/mod/cache/download/sumdb, // which will be deleted by "go clean -modcache". func (*dbClient) ReadCache(file string) ([]byte, error) { - targ := filepath.Join(PkgMod, "download/cache/sumdb", file) + targ := filepath.Join(PkgMod, "cache/download/sumdb", file) data, err := lockedfile.Read(targ) // lockedfile.Write does not atomically create the file with contents. // There is a moment between file creation and locking the file for writing, @@ -249,7 +259,7 @@ func (*dbClient) ReadCache(file string) ([]byte, error) { // WriteCache updates cached lookups or tiles. func (*dbClient) WriteCache(file string, data []byte) { - targ := filepath.Join(PkgMod, "download/cache/sumdb", file) + targ := filepath.Join(PkgMod, "cache/download/sumdb", file) os.MkdirAll(filepath.Dir(targ), 0777) lockedfile.Write(targ, bytes.NewReader(data), 0666) } diff --git a/libgo/go/cmd/go/internal/modget/get.go b/libgo/go/cmd/go/internal/modget/get.go index 491d2891c7e..1cae311c4c1 100644 --- a/libgo/go/cmd/go/internal/modget/get.go +++ b/libgo/go/cmd/go/internal/modget/get.go @@ -39,17 +39,27 @@ and then builds and installs them. The first step is to resolve which dependencies to add. For each named package or package pattern, get must decide which version of -the corresponding module to use. By default, get chooses the latest tagged +the corresponding module to use. By default, get looks up the latest tagged release version, such as v0.4.5 or v1.2.3. If there are no tagged release -versions, get chooses the latest tagged pre-release version, such as -v0.0.1-pre1. If there are no tagged versions at all, get chooses the latest -known commit. +versions, get looks up the latest tagged pre-release version, such as +v0.0.1-pre1. If there are no tagged versions at all, get looks up the latest +known commit. If the module is not already required at a later version +(for example, a pre-release newer than the latest release), get will use +the version it looked up. Otherwise, get will use the currently +required version. This default version selection can be overridden by adding an @version suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'. +The version may be a prefix: @v1 denotes the latest available version starting +with v1. See 'go help modules' under the heading 'Module queries' for the +full query syntax. + For modules stored in source control repositories, the version suffix can also be a commit hash, branch identifier, or other syntax known to the -source control system, as in 'go get golang.org/x/text@master'. +source control system, as in 'go get golang.org/x/text@master'. Note that +branches with names that overlap with other module query syntax cannot be +selected explicitly. For example, the suffix @v2 means the latest version +starting with v2, not the branch named v2. If a module under consideration is already a dependency of the current development module, then get will update the required version. @@ -59,12 +69,14 @@ dependency should be removed entirely, downgrading or removing modules depending on it as needed. The version suffix @latest explicitly requests the latest minor release of the -given path. The suffix @patch requests the latest patch release: if the path -is already in the build list, the selected version will have the same minor -version. If the path is not already in the build list, @patch is equivalent -to @latest. Neither @latest nor @patch will cause 'go get' to downgrade a module -in the build list if it is required at a newer pre-release version that is -newer than the latest released version. +module named by the given path. The suffix @upgrade is like @latest but +will not downgrade a module if it is already required at a revision or +pre-release version newer than the latest released version. The suffix +@patch requests the latest patch release: the latest released version +with the same major and minor version numbers as the currently required +version. Like @upgrade, @patch will not downgrade a module already required +at a newer version. If the path is not already required, @upgrade and @patch +are equivalent to @latest. Although get defaults to using the latest version of the module containing a named package, it does not use the latest version of that module's @@ -178,7 +190,7 @@ func (v *upgradeFlag) Set(s string) error { s = "" } if s == "true" { - s = "latest" + s = "upgrade" } *v = upgradeFlag(s) return nil @@ -202,8 +214,9 @@ type getArg struct { // if there is no "@"). path specifies the modules or packages to get. path string - // vers is the part of the argument after "@" (or "" if there is no "@"). - // vers specifies the module version to get. + // vers is the part of the argument after "@" or an implied + // "upgrade" or "patch" if there is no "@". vers specifies the + // module version to get. vers string } @@ -249,7 +262,7 @@ func runGet(cmd *base.Command, args []string) { } switch getU { - case "", "latest", "patch": + case "", "upgrade", "patch": // ok default: base.Fatalf("go get: unknown upgrade flag -u=%s", getU) @@ -283,11 +296,11 @@ func runGet(cmd *base.Command, args []string) { // Parse command-line arguments and report errors. The command-line // arguments are of the form path@version or simply path, with implicit - // @latest. path@none is "downgrade away". + // @upgrade. path@none is "downgrade away". var gets []getArg var queries []*query for _, arg := range search.CleanPatterns(args) { - // Argument is module query path@vers, or else path with implicit @latest. + // Argument is path or path@vers. path := arg vers := "" if i := strings.Index(arg, "@"); i >= 0 { @@ -298,10 +311,14 @@ func runGet(cmd *base.Command, args []string) { continue } - // If the user runs 'go get -u=patch some/module', update some/module to a - // patch release, not a minor version. - if vers == "" && getU != "" { - vers = string(getU) + // If no version suffix is specified, assume @upgrade. + // If -u=patch was specified, assume @patch instead. + if vers == "" { + if getU != "" { + vers = string(getU) + } else { + vers = "upgrade" + } } gets = append(gets, getArg{raw: arg, path: path, vers: vers}) @@ -358,7 +375,7 @@ func runGet(cmd *base.Command, args []string) { // The argument is a package path. if pkgs := modload.TargetPackages(path); len(pkgs) != 0 { // The path is in the main module. Nothing to query. - if vers != "" && vers != "latest" && vers != "patch" { + if vers != "upgrade" && vers != "patch" { base.Errorf("go get %s: can't request explicit version of path in main module", arg) } continue @@ -376,8 +393,8 @@ func runGet(cmd *base.Command, args []string) { continue } - // If we're querying "latest" or "patch", we need to know the current - // version of the module. For "latest", we want to avoid accidentally + // If we're querying "upgrade" or "patch", we need to know the current + // version of the module. For "upgrade", we want to avoid accidentally // downgrading from a newer prerelease. For "patch", we need to query // the correct minor version. // Here, we check if "path" is the name of a module in the build list @@ -718,7 +735,7 @@ func runQueries(cache map[querySpec]*query, queries []*query, modOnly map[string return byPath } -// getQuery evaluates the given package path, version pair +// getQuery evaluates the given (package or module) path and version // to determine the underlying module version being requested. // If forceModulePath is set, getQuery must interpret path // as a module path. @@ -736,34 +753,51 @@ func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (mo base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set") } - if vers == "" || vers == "patch" && prevM.Version == "" { - vers = "latest" - } - - if forceModulePath || !strings.Contains(path, "...") { + // If the query must be a module path, try only that module path. + if forceModulePath { if path == modload.Target.Path { if vers != "latest" { return module.Version{}, fmt.Errorf("can't get a specific version of the main module") } } - // If the path doesn't contain a wildcard, try interpreting it as a module path. info, err := modload.Query(path, vers, prevM.Version, modload.Allowed) if err == nil { return module.Version{Path: path, Version: info.Version}, nil } - // If the query fails, and the path must be a real module, report the query error. - if forceModulePath { - return module.Version{}, err + // If the query was "upgrade" or "patch" and the current version has been + // replaced, check to see whether the error was for that same version: + // if so, the version was probably replaced because it is invalid, + // and we should keep that replacement without complaining. + if vers == "upgrade" || vers == "patch" { + var vErr *module.InvalidVersionError + if errors.As(err, &vErr) && vErr.Version == prevM.Version && modload.Replacement(prevM).Path != "" { + return prevM, nil + } } + + return module.Version{}, err } - // Otherwise, try a package path or pattern. + // If the query may be either a package or a module, try it as a package path. + // If it turns out to only exist as a module, we can detect the resulting + // PackageNotInModuleError and avoid a second round-trip through (potentially) + // all of the configured proxies. results, err := modload.QueryPattern(path, vers, modload.Allowed) if err != nil { + // If the path doesn't contain a wildcard, check whether it was actually a + // module path instead. If so, return that. + if !strings.Contains(path, "...") { + var modErr *modload.PackageNotInModuleError + if errors.As(err, &modErr) && modErr.Mod.Path == path { + return modErr.Mod, nil + } + } + return module.Version{}, err } + return results[0].Mod, nil } @@ -893,13 +927,23 @@ func (u *upgrader) Upgrade(m module.Version) (module.Version, error) { // which may return a pseudoversion for the latest commit. // Query "latest" returns the newest tagged version or the newest // prerelease version if there are no non-prereleases, or repo.Latest - // if there aren't any tagged versions. Since we're providing the previous - // version, Query will confirm the latest version is actually newer - // and will return the current version if not. + // if there aren't any tagged versions. + // If we're querying "upgrade" or "patch", Query will compare the current + // version against the chosen version and will return the current version + // if it is newer. info, err := modload.Query(m.Path, string(getU), m.Version, modload.Allowed) if err != nil { // Report error but return m, to let version selection continue. // (Reporting the error will fail the command at the next base.ExitIfErrors.) + + // Special case: if the error is for m.Version itself and m.Version has a + // replacement, then keep it and don't report the error: the fact that the + // version is invalid is likely the reason it was replaced to begin with. + var vErr *module.InvalidVersionError + if errors.As(err, &vErr) && vErr.Version == m.Version && modload.Replacement(m).Path != "" { + return m, nil + } + // Special case: if the error is "no matching versions" then don't // even report the error. Because Query does not consider pseudo-versions, // it may happen that we have a pseudo-version but during -u=patch diff --git a/libgo/go/cmd/go/internal/modload/build.go b/libgo/go/cmd/go/internal/modload/build.go index 17a65216c2a..7cbdef1c36c 100644 --- a/libgo/go/cmd/go/internal/modload/build.go +++ b/libgo/go/cmd/go/internal/modload/build.go @@ -79,7 +79,7 @@ func addUpdate(m *modinfo.ModulePublic) { return } - if info, err := Query(m.Path, "latest", m.Version, Allowed); err == nil && semver.Compare(info.Version, m.Version) > 0 { + if info, err := Query(m.Path, "upgrade", m.Version, Allowed); err == nil && semver.Compare(info.Version, m.Version) > 0 { m.Update = &modinfo.ModulePublic{ Path: m.Path, Version: info.Version, diff --git a/libgo/go/cmd/go/internal/modload/help.go b/libgo/go/cmd/go/internal/modload/help.go index 788544c2c85..1927c1cff73 100644 --- a/libgo/go/cmd/go/internal/modload/help.go +++ b/libgo/go/cmd/go/internal/modload/help.go @@ -231,12 +231,25 @@ evaluates to the available tagged version nearest to the comparison target The string "latest" matches the latest available tagged version, or else the underlying source repository's latest untagged revision. -A revision identifier for the underlying source repository, -such as a commit hash prefix, revision tag, or branch name, -selects that specific code revision. If the revision is -also tagged with a semantic version, the query evaluates to -that semantic version. Otherwise the query evaluates to a -pseudo-version for the commit. +The string "upgrade" is like "latest", but if the module is +currently required at a later version than the version "latest" +would select (for example, a newer pre-release version), "upgrade" +will select the later version instead. + +The string "patch" matches the latest available tagged version +of a module with the same major and minor version numbers as the +currently required version. If no version is currently required, +"patch" is equivalent to "latest". + +A revision identifier for the underlying source repository, such as +a commit hash prefix, revision tag, or branch name, selects that +specific code revision. If the revision is also tagged with a +semantic version, the query evaluates to that semantic version. +Otherwise the query evaluates to a pseudo-version for the commit. +Note that branches and tags with names that are matched by other +query syntax cannot be selected this way. For example, the query +"v2" means the latest version starting with "v2", not the branch +named "v2". All queries prefer release versions to pre-release versions. For example, "=v0.0.0", vers: "v0.0.0"}, {path: queryRepo, query: "v0.0.1", vers: "v0.0.1"}, {path: queryRepo, query: "v0.0.1+foo", vers: "v0.0.1"}, - {path: queryRepo, query: "v0.0.99", err: `unknown revision v0.0.99`}, + {path: queryRepo, query: "v0.0.99", err: `vcs-test.golang.org/git/querytest.git@v0.0.99: invalid version: unknown revision v0.0.99`}, {path: queryRepo, query: "v0", vers: "v0.3.0"}, {path: queryRepo, query: "v0.1", vers: "v0.1.2"}, {path: queryRepo, query: "v0.2", err: `no matching versions for query "v0.2"`}, @@ -112,15 +112,17 @@ var queryTests = []struct { // unconditionally). {path: queryRepo, query: "42abcb6df8ee", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, - {path: queryRepo, query: "v1.9.10-pre2+wrongmetadata", err: `unknown revision v1.9.10-pre2+wrongmetadata`}, - {path: queryRepo, query: "v1.9.10-pre2", err: `unknown revision v1.9.10-pre2`}, + {path: queryRepo, query: "v1.9.10-pre2+wrongmetadata", err: `vcs-test.golang.org/git/querytest.git@v1.9.10-pre2+wrongmetadata: invalid version: unknown revision v1.9.10-pre2+wrongmetadata`}, + {path: queryRepo, query: "v1.9.10-pre2", err: `vcs-test.golang.org/git/querytest.git@v1.9.10-pre2: invalid version: unknown revision v1.9.10-pre2`}, {path: queryRepo, query: "latest", vers: "v1.9.9"}, - {path: queryRepo, query: "latest", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"}, - {path: queryRepo, query: "latest", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, - {path: queryRepo, query: "latest", current: "v0.0.0-20190513201126-42abcb6df8ee", vers: "v0.0.0-20190513201126-42abcb6df8ee"}, - {path: queryRepo, query: "latest", allow: "NOMATCH", err: `no matching versions for query "latest"`}, - {path: queryRepo, query: "latest", current: "v1.9.9", allow: "NOMATCH", err: `no matching versions for query "latest" (current version is v1.9.9)`}, - {path: queryRepo, query: "latest", current: "v1.99.99", err: `unknown revision v1.99.99`}, + {path: queryRepo, query: "latest", current: "v1.9.10-pre1", vers: "v1.9.9"}, + {path: queryRepo, query: "upgrade", vers: "v1.9.9"}, + {path: queryRepo, query: "upgrade", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"}, + {path: queryRepo, query: "upgrade", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, + {path: queryRepo, query: "upgrade", current: "v0.0.0-20190513201126-42abcb6df8ee", vers: "v0.0.0-20190513201126-42abcb6df8ee"}, + {path: queryRepo, query: "upgrade", allow: "NOMATCH", err: `no matching versions for query "upgrade"`}, + {path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `no matching versions for query "upgrade" (current version is v1.9.9)`}, + {path: queryRepo, query: "upgrade", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`}, {path: queryRepo, query: "patch", current: "", vers: "v1.9.9"}, {path: queryRepo, query: "patch", current: "v0.1.0", vers: "v0.1.2"}, {path: queryRepo, query: "patch", current: "v1.9.0", vers: "v1.9.9"}, @@ -159,8 +161,11 @@ var queryTests = []struct { {path: queryRepoV2, query: "v2.6.0-pre1", vers: "v2.6.0-pre1"}, {path: queryRepoV2, query: "latest", vers: "v2.5.5"}, - {path: queryRepoV3, query: "e0cf3de987e6", vers: "v3.0.0-20180704024501-e0cf3de987e6"}, - {path: queryRepoV3, query: "latest", vers: "v3.0.0-20180704024501-e0cf3de987e6"}, + // e0cf3de987e6 is the latest commit on the master branch, and it's actually + // v1.19.10-pre1, not anything resembling v3: attempting to query it as such + // should fail. + {path: queryRepoV3, query: "e0cf3de987e6", err: `vcs-test.golang.org/git/querytest.git/v3@v3.0.0-20180704024501-e0cf3de987e6: invalid version: go.mod has non-.../v3 module path "vcs-test.golang.org/git/querytest.git" (and .../v3/go.mod does not exist) at revision e0cf3de987e6`}, + {path: queryRepoV3, query: "latest", err: `no matching versions for query "latest"`}, {path: emptyRepo, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"}, {path: emptyRepo, query: ">v0.0.0", err: `no matching versions for query ">v0.0.0"`}, @@ -180,7 +185,10 @@ func TestQuery(t *testing.T) { ok, _ := path.Match(allow, m.Version) return ok } + tt := tt t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.query+"/"+tt.current+"/"+allow, func(t *testing.T) { + t.Parallel() + info, err := Query(tt.path, tt.query, tt.current, allowed) if tt.err != "" { if err == nil { diff --git a/libgo/go/cmd/go/internal/mvs/mvs.go b/libgo/go/cmd/go/internal/mvs/mvs.go index 568efbd8b26..4e7a828c24f 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs.go +++ b/libgo/go/cmd/go/internal/mvs/mvs.go @@ -216,8 +216,8 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m } } - // Construct the list by traversing the graph again, replacing older - // modules with required minimum versions. + // The final list is the minimum version of each module found in the graph. + if v := min[target.Path]; v != target.Version { // TODO(jayconrod): there is a special case in modload.mvsReqs.Max // that prevents us from selecting a newer version of a module @@ -228,19 +228,18 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m } list := []module.Version{target} - listed := map[string]bool{target.Path: true} - for i := 0; i < len(list); i++ { - n := modGraph[list[i]] + for path, vers := range min { + if path != target.Path { + list = append(list, module.Version{Path: path, Version: vers}) + } + + n := modGraph[module.Version{Path: path, Version: vers}] required := n.required for _, r := range required { v := min[r.Path] if r.Path != target.Path && reqs.Max(v, r.Version) != v { panic(fmt.Sprintf("mistake: version %q does not satisfy requirement %+v", v, r)) // TODO: Don't panic. } - if !listed[r.Path] { - list = append(list, module.Version{Path: r.Path, Version: v}) - listed[r.Path] = true - } } } @@ -289,12 +288,12 @@ func Req(target module.Version, list []module.Version, base []string, reqs Reqs) } // Walk modules in reverse post-order, only adding those not implied already. - have := map[string]string{} + have := map[module.Version]bool{} walk = func(m module.Version) error { - if v, ok := have[m.Path]; ok && reqs.Max(m.Version, v) == v { + if have[m] { return nil } - have[m.Path] = m.Version + have[m] = true for _, m1 := range reqCache[m] { walk(m1) } @@ -322,7 +321,7 @@ func Req(target module.Version, list []module.Version, base []string, reqs Reqs) // Older version. continue } - if have[m.Path] != m.Version { + if !have[m] { min = append(min, m) walk(m) } diff --git a/libgo/go/cmd/go/internal/mvs/mvs_test.go b/libgo/go/cmd/go/internal/mvs/mvs_test.go index cab4bb241bc..72d3ea95b79 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs_test.go +++ b/libgo/go/cmd/go/internal/mvs/mvs_test.go @@ -29,7 +29,7 @@ D5: E2 G1: C4 A2: B1 C4 D4 build A: A B1 C2 D4 E2 F1 -upgrade* A: A B1 C4 D5 E2 G1 +upgrade* A: A B1 C4 D5 E2 F1 G1 upgrade A C4: A B1 C4 D4 E2 F1 G1 downgrade A2 D2: A2 C4 D2 @@ -38,7 +38,7 @@ A: B1 C2 B1: D3 C2: B2 B2: -build A: A B2 C2 +build A: A B2 C2 D3 # Cross-dependency between D and E. # No matter how it arises, should get result of merging all build lists via max, @@ -157,7 +157,18 @@ D1: E2 E1: D2 build A: A B C D2 E2 -# Upgrade from B1 to B2 should drop the transitive dep on D. +# golang.org/issue/31248: +# Even though we select X2, the requirement on I1 +# via X1 should be preserved. +name: cross8 +M: A1 B1 +A1: X1 +B1: X2 +X1: I1 +X2: +build M: M A1 B1 I1 X2 + +# Upgrade from B1 to B2 should not drop the transitive dep on D. name: drop A: B1 C1 B1: D1 @@ -165,14 +176,14 @@ B2: C2: D2: build A: A B1 C1 D1 -upgrade* A: A B2 C2 +upgrade* A: A B2 C2 D2 name: simplify A: B1 C1 B1: C2 C1: D1 C2: -build A: A B1 C2 +build A: A B1 C2 D1 name: up1 A: B1 C1 @@ -254,8 +265,9 @@ build A: A B1 upgrade A B2: A B2 upgrade* A: A B3 +# golang.org/issue/29773: # Requirements of older versions of the target -# must not be carried over. +# must be carried over. name: cycle2 A: B1 A1: C1 @@ -265,8 +277,8 @@ B2: A2 C1: A2 C2: D2: -build A: A B1 -upgrade* A: A B2 +build A: A B1 C1 D1 +upgrade* A: A B2 C2 D2 # Requirement minimization. @@ -283,6 +295,14 @@ H1: G1 req A: G1 req A G: G1 req A H: H1 + +name: req3 +M: A1 B1 +A1: X1 +B1: X2 +X1: I1 +X2: +req M: A1 B1 ` func Test(t *testing.T) { diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index eed2d437c99..95000011d83 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -843,7 +843,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin if !cfg.BuildN { // writeTestmain writes _testmain.go, // using the test description gathered in t. - if err := ioutil.WriteFile(testDir+"_testmain.go", pmain.Internal.TestmainGo, 0666); err != nil { + if err := ioutil.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil { return nil, nil, nil, err } } @@ -1250,6 +1250,15 @@ func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bo return false } + if a.Package.Root == "" { + // Caching does not apply to tests outside of any module, GOPATH, or GOROOT. + if cache.DebugTest { + fmt.Fprintf(os.Stderr, "testcache: caching disabled for package outside of module root, GOPATH, or GOROOT: %s\n", a.Package.ImportPath) + } + c.disableCache = true + return false + } + var cacheArgs []string for _, arg := range testArgs { i := strings.Index(arg, "=") @@ -1437,8 +1446,8 @@ func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) if !filepath.IsAbs(name) { name = filepath.Join(pwd, name) } - if !inDir(name, a.Package.Root) { - // Do not recheck files outside the GOPATH or GOROOT root. + if a.Package.Root == "" || !inDir(name, a.Package.Root) { + // Do not recheck files outside the module, GOPATH, or GOROOT root. break } fmt.Fprintf(h, "stat %s %x\n", name, hashStat(name)) @@ -1446,8 +1455,8 @@ func computeTestInputsID(a *work.Action, testlog []byte) (cache.ActionID, error) if !filepath.IsAbs(name) { name = filepath.Join(pwd, name) } - if !inDir(name, a.Package.Root) { - // Do not recheck files outside the GOPATH or GOROOT root. + if a.Package.Root == "" || !inDir(name, a.Package.Root) { + // Do not recheck files outside the module, GOPATH, or GOROOT root. break } fh, err := hashOpen(name) diff --git a/libgo/go/cmd/go/internal/version/exe.go b/libgo/go/cmd/go/internal/version/exe.go index 55da960c025..0e7deef1491 100644 --- a/libgo/go/cmd/go/internal/version/exe.go +++ b/libgo/go/cmd/go/internal/version/exe.go @@ -103,6 +103,11 @@ func (x *elfExe) ReadData(addr, size uint64) ([]byte, error) { } func (x *elfExe) DataStart() uint64 { + for _, s := range x.f.Sections { + if s.Name == ".go.buildinfo" { + return s.Addr + } + } for _, p := range x.f.Progs { if p.Type == elf.PT_LOAD && p.Flags&(elf.PF_X|elf.PF_W) == elf.PF_W { return p.Vaddr @@ -208,7 +213,13 @@ func (x *machoExe) ReadData(addr, size uint64) ([]byte, error) { } func (x *machoExe) DataStart() uint64 { - // Assume data is first non-empty writable segment. + // Look for section named "__go_buildinfo". + for _, sec := range x.f.Sections { + if sec.Name == "__go_buildinfo" { + return sec.Addr + } + } + // Try the first non-empty writable segment. const RW = 3 for _, load := range x.f.Loads { seg, ok := load.(*macho.Segment) diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go index ed5a149da35..9305b2d859c 100644 --- a/libgo/go/cmd/go/internal/work/build.go +++ b/libgo/go/cmd/go/internal/work/build.go @@ -30,6 +30,8 @@ along with their dependencies, but it does not install the results. If the arguments to build are a list of .go files from a single directory, build treats them as a list of source files specifying a single package. +When compiling packages, build ignores files that end in '_test.go'. + When compiling a single main package, build writes the resulting executable to an output file named after the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe') @@ -40,8 +42,6 @@ When compiling multiple packages or a single non-main package, build compiles the packages but discards the resulting object, serving only as a check that the packages can be built. -When compiling packages, build ignores files that end in '_test.go'. - The -o flag forces build to write the resulting executable or object to the named output file or directory, instead of the default behavior described in the last two paragraphs. If the named output is a directory that exists, diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 5ff9337afec..27bde8c6151 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -203,8 +203,9 @@ func (b *Builder) toolID(name string) string { // On the development branch, use the content ID part of the build ID. id = contentID(f[len(f)-1]) } else { - // For a release, the output is like: "compile version go1.9.1". Use the whole line. - id = f[2] + // For a release, the output is like: "compile version go1.9.1 X:framepointer". + // Use the whole line. + id = strings.TrimSpace(line) } b.id.Lock() diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 8e92f9461cf..c666026213b 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -542,15 +542,6 @@ func (b *Builder) build(a *Action) (err error) { } } - // Write out the _testinginit.go file for any test packages that import "testing". - if a.Package.Internal.TestinginitGo != nil { - initfile := objdir + "_testinginit.go" - if err := b.writeFile(initfile, a.Package.Internal.TestinginitGo); err != nil { - return err - } - gofiles = append([]string{initfile}, gofiles...) - } - // Run cgo. if a.Package.UsesCgo() || a.Package.UsesSwig() { // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc. diff --git a/libgo/go/cmd/go/testdata/flag_test.go b/libgo/go/cmd/go/testdata/flag_test.go index a4e5507f2cd..ddf613d8701 100644 --- a/libgo/go/cmd/go/testdata/flag_test.go +++ b/libgo/go/cmd/go/testdata/flag_test.go @@ -1,19 +1,16 @@ -// Copyright 2019 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. - package flag_test import ( "flag" + "log" "testing" ) var v = flag.Int("v", 0, "v flag") -// Run this as go test pkg -args -v=7 +// Run this as go test pkg -v=7 func TestVFlagIsSet(t *testing.T) { if *v != 7 { - t.Fatal("v flag not set") + log.Fatal("v flag not set") } } diff --git a/libgo/go/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt index da19ebd9ec9..36bc2c67266 100644 --- a/libgo/go/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt +++ b/libgo/go/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt @@ -1,7 +1,7 @@ example.com/badchain/c v1.1.0 -- .mod -- -module example.com/badchain/wrong +module badchain.example.com/c -- .info -- {"Version":"v1.1.0"} -- c.go -- diff --git a/libgo/go/cmd/go/testdata/script/build_cache_output.txt b/libgo/go/cmd/go/testdata/script/build_cache_output.txt index 89e3ff0f1ec..0d94bf61a9a 100644 --- a/libgo/go/cmd/go/testdata/script/build_cache_output.txt +++ b/libgo/go/cmd/go/testdata/script/build_cache_output.txt @@ -1,4 +1,5 @@ env GO111MODULE=off +env GODEBUG=gocachetest=1 [!gc] skip [short] skip # clears cache, rebuilds too much @@ -32,7 +33,7 @@ stderr 'main.go:2.* can inline main' # from compiler stderr '\d+ symbols' # from linker # Running a test should run the compiler, linker, and the test the first time. -go test -v -x -gcflags=-m -ldflags=-v p_test.go +go test -v -x -gcflags=-m -ldflags=-v p stderr 'compile( |\.exe"?)' stderr 'p_test.go:.*can inline Test' # from compile of p_test stderr 'testmain\.go:.*inlin' # from compile of testmain @@ -42,7 +43,7 @@ stderr 'p\.test( |\.exe"?)' stdout 'TEST' # from test # ... but not the second, even though it still prints the compiler, linker, and test output. -go test -v -x -gcflags=-m -ldflags=-v p_test.go +go test -v -x -gcflags=-m -ldflags=-v p ! stderr 'compile( |\.exe"?)' stderr 'p_test.go:.*can inline Test' # from compile of p_test stderr 'testmain\.go:.*inlin' # from compile of testmain @@ -60,7 +61,7 @@ func f(x *int) *int { return x } package main func main() {} --- p_test.go -- +-- p/p_test.go -- package p import "testing" func Test(t *testing.T) {println("TEST")} diff --git a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt new file mode 100644 index 00000000000..ba94f9bd3eb --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt @@ -0,0 +1,16 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/31031: +# Importing or loading a non-existent package in cmd/ should print +# a clear error in module mode. + +! go list cmd/unknown +stderr '^can''t load package: package cmd/unknown: package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' + +go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go +stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' + +-- x.go -- +package x + +import _ "cmd/unknown" diff --git a/libgo/go/cmd/go/testdata/script/mod_doc.txt b/libgo/go/cmd/go/testdata/script/mod_doc.txt index 40acbc5ac08..d7aa553c1d3 100644 --- a/libgo/go/cmd/go/testdata/script/mod_doc.txt +++ b/libgo/go/cmd/go/testdata/script/mod_doc.txt @@ -3,6 +3,7 @@ env GO111MODULE=on [short] skip +# Check when module x is inside GOPATH/src. go doc y stdout 'Package y is.*alphabet' stdout 'import "x/y"' @@ -16,13 +17,25 @@ stdout 'Hello returns a greeting' go doc quote stdout 'Package quote collects pithy sayings.' -# Double-check go doc y when y is not in GOPATH/src. -env GOPATH=$WORK/altgopath +# Double-check when module x is outside GOPATH/src. +env GOPATH=$WORK/emptygopath go doc x/y stdout 'Package y is.*alphabet' go doc y stdout 'Package y is.*alphabet' +# Triple-check when module x is outside GOPATH/src, +# but other packages with same import paths are in GOPATH/src. +# Since go doc is running in module mode here, packages in active module +# should be preferred over packages in GOPATH. See golang.org/issue/28992. +env GOPATH=$WORK/gopath2 +go doc x/y +! stdout 'Package y is.*GOPATH' +stdout 'Package y is.*alphabet' +go doc rsc.io/quote +! stdout 'Package quote is located in a GOPATH workspace.' +stdout 'Package quote collects pithy sayings.' + -- go.mod -- module x require rsc.io/quote v1.5.2 @@ -33,3 +46,13 @@ package y -- x.go -- package x + +-- $WORK/gopath2/src/x/y/y.go -- +// Package y is located in a GOPATH workspace. +package y +-- $WORK/gopath2/src/rsc.io/quote/quote.go -- +// Package quote is located in a GOPATH workspace. +package quote + +// Hello is located in a GOPATH workspace. +func Hello() string { return "" } diff --git a/libgo/go/cmd/go/testdata/script/mod_dot.txt b/libgo/go/cmd/go/testdata/script/mod_dot.txt new file mode 100644 index 00000000000..c90074d0a6b --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_dot.txt @@ -0,0 +1,36 @@ +env GO111MODULE=on + +# golang.org/issue/32917 and golang.org/issue/28459: 'go build' and 'go test' +# in an empty directory should refer to the path '.' and should not attempt +# to resolve an external module. +cd dir +! go get . +stderr 'go get \.: path .* is not a package in module rooted at .*[/\\]dir$' +! go list +! stderr 'cannot find module providing package' +stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' + +cd subdir +! go list +! stderr 'cannot find module providing package' +stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' +cd .. + +# golang.org/issue/30590: if a package is found in the filesystem +# but is not in the main module, the error message should not say +# "cannot find module providing package", and we shouldn't try +# to find a module providing the package. +! go list ./othermodule +! stderr 'cannot find module providing package' +stderr 'go: directory othermodule is outside main module' + +-- dir/go.mod -- +module example.com +go 1.13 +-- dir/subdir/README -- +There are no Go source files in this directory. +-- dir/othermodule/go.mod -- +module example.com/othermodule +go 1.13 +-- dir/othermodule/om.go -- +package othermodule diff --git a/libgo/go/cmd/go/testdata/script/mod_download.txt b/libgo/go/cmd/go/testdata/script/mod_download.txt index c6729c71a29..9eb3140c332 100644 --- a/libgo/go/cmd/go/testdata/script/mod_download.txt +++ b/libgo/go/cmd/go/testdata/script/mod_download.txt @@ -17,6 +17,7 @@ stderr 'this.domain.is.invalid' stdout '"Error": ".*this.domain.is.invalid.*"' # download -json with version should print JSON +# and download the .info file for the 'latest' version. go mod download -json 'rsc.io/quote@<=v1.5.0' stdout '^\t"Path": "rsc.io/quote"' stdout '^\t"Version": "v1.5.0"' @@ -27,13 +28,14 @@ stdout '^\t"Sum": "h1:6fJa6E\+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE="' # hash of stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="' ! stdout '"Error"' +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info + # download queries above should not have added to go.mod. go list -m all ! stdout rsc.io # add to go.mod so we can test non-query downloads go mod edit -require rsc.io/quote@v1.5.2 -! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip @@ -83,6 +85,16 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip go mod download -json rsc.io/quote@v1.5.1 exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip +# download reports errors encountered when locating modules +! go mod download bad/path +stderr '^module bad/path: not a known dependency$' +! go mod download bad/path@latest +stderr '^bad/path@latest: malformed module path "bad/path": missing dot in first path element$' +! go mod download rsc.io/quote@v1.999.999 +stderr '^rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' +! go mod download -json bad/path +stdout '^\t"Error": "module bad/path: not a known dependency"' + # allow go mod download without go.mod env GO111MODULE=auto rm go.mod diff --git a/libgo/go/cmd/go/testdata/script/mod_download_latest.txt b/libgo/go/cmd/go/testdata/script/mod_download_latest.txt new file mode 100644 index 00000000000..60d860e4da4 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_download_latest.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +# If the module is the latest version of itself, +# the Latest field should be set. +go mod download -json rsc.io/quote@v1.5.2 +stdout '"Latest":\s*true' + +# If the module is older than latest, the field should be unset. +go mod download -json rsc.io/quote@v1.5.1 +! stdout '"Latest":' + +# If the module is newer than "latest", the field should be unset... +go mod download -json rsc.io/quote@v1.5.3-pre1 +! stdout '"Latest":' + +# ...even if that version is also what is required by the main module. +go mod init example.com +go mod edit -require rsc.io/quote@v1.5.3-pre1 +go mod download -json rsc.io/quote@v1.5.3-pre1 +! stdout '"Latest":' diff --git a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt index 9341a1d0830..fd7de130024 100644 --- a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt @@ -34,11 +34,11 @@ stderr 'import lookup disabled' ! go build -mod=readonly ./nonexist ! stderr 'import lookup disabled' -stderr 'unknown import path "m/nonexist": cannot find package' +stderr '^can.t load package: package ./nonexist: cannot find package "." in:\n\t'$WORK'[/\\]gopath[/\\]src[/\\]x[/\\]nonexist$' ! go build -mod=readonly ./go.mod ! stderr 'import lookup disabled' -stderr 'unknown import path "m/go.mod": cannot find package' +stderr 'can.t load package: package ./go.mod: cannot find package' -- x/go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_get_fallback.txt b/libgo/go/cmd/go/testdata/script/mod_get_fallback.txt new file mode 100644 index 00000000000..a9834a324e2 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_get_fallback.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on + +[!net] skip + +env GOPROXY=https://proxy.golang.org,direct +env GOSUMDB=off + +go get -x -v -d golang.org/x/tools/cmd/goimports +stderr '# get https://proxy.golang.org/golang.org/x/tools/@latest' +! stderr '# get https://golang.org' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_main.txt b/libgo/go/cmd/go/testdata/script/mod_get_main.txt index 8e06220f9e6..403abcd28ba 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_main.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_main.txt @@ -4,13 +4,19 @@ env GO111MODULE=on # @patch and @latest within the main module refer to the current version. # The main module won't be upgraded, but missing dependencies will be added. cp go.mod.orig go.mod -go get -d rsc.io/x@latest +go get -d rsc.io/x +grep 'rsc.io/quote v1.5.2' go.mod +go get -d rsc.io/x@upgrade grep 'rsc.io/quote v1.5.2' go.mod cp go.mod.orig go.mod go get -d rsc.io/x@patch grep 'rsc.io/quote v1.5.2' go.mod cp go.mod.orig go.mod +# The main module cannot be updated to @latest, which is a specific version. +! go get -d rsc.io/x@latest +stderr '^go get rsc.io/x@latest: can.t request explicit version of path in main module$' + # The main module cannot be updated to a specific version. ! go get rsc.io/x@v0.1.0 stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt b/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt index 9616863383d..b1838f824a6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt @@ -1,6 +1,7 @@ env GO111MODULE=on # Download modules to avoid stderr chatter +go mod download example.com@v1.0.0 go mod download example.com/newcycle/a@v1.0.0 go mod download example.com/newcycle/a@v1.0.1 go mod download example.com/newcycle/b@v1.0.0 @@ -10,5 +11,6 @@ go mod init m cmp stderr stderr-expected -- stderr-expected -- +go: finding example.com/newcycle v1.0.0 go get: inconsistent versions: example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1 (not example.com/newcycle/a@v1.0.0) diff --git a/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt b/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt index b9931970e0d..bfab70090cf 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt @@ -10,11 +10,11 @@ grep 'require rsc.io/quote' go.mod cp go.mod.orig go.mod ! go get -d rsc.io/quote/x... -stderr 'go get rsc.io/quote/x...: module rsc.io/quote@latest \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x...' +stderr 'go get rsc.io/quote/x...: module rsc.io/quote@upgrade \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x...' ! grep 'require rsc.io/quote' go.mod ! go get -d rsc.io/quote/x/... -stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@latest \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x/...' +stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@upgrade \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x/...' ! grep 'require rsc.io/quote' go.mod # If a pattern matches no packages within a module, the module should not diff --git a/libgo/go/cmd/go/testdata/script/mod_get_svn.txt b/libgo/go/cmd/go/testdata/script/mod_get_svn.txt index b3436284aff..cd19d99dbcc 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_svn.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_svn.txt @@ -2,19 +2,26 @@ [!exec:svn] skip env GO111MODULE=on -env GOPROXY=direct # obtain llvm.org directory, not via svn. +env GOPROXY=direct +env GOSUMDB=off # Attempting to get a module zip using svn should fail with a reasonable # message instead of a panic. # TODO(golang.org/issue/26092): Really, it shouldn't fail at all. -! go get -d llvm.org/llvm/bindings/go/llvm +! go get -d vcs-test.golang.org/svn/hello.svn stderr 'ReadZip not implemented for svn' ! go install . stderr 'ReadZip not implemented for svn' +# Attempting to get a nonexistent module using svn should fail with a +# reasonable message instead of a panic. +! go get -d vcs-test.golang.org/svn/nonexistent.svn +! stderr panic +stderr 'go get vcs-test.golang.org/svn/nonexistent.svn: no matching versions for query "upgrade"' + -- go.mod -- module golang/go/issues/28943/main -- main.go -- package main -import _ "llvm.org/llvm/bindings/go/llvm" +import _ "vcs-test.golang.org/svn/hello.svn" func main() {} diff --git a/libgo/go/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt b/libgo/go/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt index 9184d85f7f3..f5f415aa3fa 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt @@ -9,18 +9,33 @@ env GO111MODULE=on # The v0.1.1 pseudo-version is semantically higher than the latest tag. # The v0.0.0 pseudo-version is chronologically newer. -# 'get -u' should not downgrade to the (lower) tagged version. +# Start at v0.1.1-0.20190429073117-b5426c86b553 go get -d example.com/pseudoupgrade@b5426c8 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get -u' should not downgrade to the (lower) tagged version. go get -d -u go list -m -u all stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' -# 'get example.com/pseudoupgrade@latest' should not downgrade to -# the (lower) tagged version. -go get -d example.com/pseudoupgrade@latest +# 'get example.com/pseudoupgrade@upgrade' should not downgrade. +go get -d example.com/pseudoupgrade@upgrade go list -m all stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' +# 'get example.com/pseudoupgrade' should not downgrade. +# This is equivalent to 'get example.com/pseudoupgrade@upgrade'. +go get -d example.com/pseudoupgrade +go list -m all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade@latest' should downgrade. +# @latest should not consider the current version. +go get -d example.com/pseudoupgrade@latest +go list -m all +stdout '^example.com/pseudoupgrade v0.1.0$' + # We should observe the same behavior with the newer pseudo-version. go get -d example.com/pseudoupgrade@v0.0.0-20190430073000-30950c05d534 @@ -29,12 +44,21 @@ go get -d -u go list -m -u all stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' -# 'get example.com/pseudoupgrade@latest' should not downgrade to the -# chronologically older tagged version. -go get -d example.com/pseudoupgrade@latest +# 'get example.com/pseudoupgrade@upgrade should not downgrade. +go get -d example.com/pseudoupgrade@upgrade go list -m -u all stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' +# 'get example.com/pseudoupgrade' should not downgrade. +go get -d example.com/pseudoupgrade +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade@latest' should downgrade. +go get -d example.com/pseudoupgrade@latest +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.0$' + -- go.mod -- module x diff --git a/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt b/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt index a4eb5d6596f..ae05250c5f6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt @@ -62,15 +62,31 @@ import ( "go/build" "log" "os" + "path/filepath" "strings" ) func main() { - p, err := build.Import(os.Args[1], os.Args[2], 0) + // build.Import should support relative and absolute source dir paths. + path := os.Args[1] + srcDir := os.Args[2] + p1, err := build.Import(path, srcDir, 0) if err != nil { log.Fatal(err) } - fmt.Printf("%s\n%s\n", p.Dir, strings.Join(p.GoFiles, " ")) + absSrcDir, err := filepath.Abs(srcDir) + if err != nil { + log.Fatal(err) + } + p2, err := build.Import(path, absSrcDir, 0) + if err != nil { + log.Fatal(err) + } + if p1.Dir != p2.Dir { + log.Fatalf("different packages loaded with relative and absolute paths:\n\t%s\n\t%s", p1.Dir, p2.Dir) + } + + fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " ")) } -- $GOPATH/other/go.mod -- diff --git a/libgo/go/cmd/go/testdata/script/mod_indirect.txt b/libgo/go/cmd/go/testdata/script/mod_indirect.txt new file mode 100644 index 00000000000..87a3f0b10f7 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_indirect.txt @@ -0,0 +1,81 @@ +env GO111MODULE=on + +# golang.org/issue/31248: module requirements imposed by dependency versions +# older than the selected version must still be taken into account. + +env GOFLAGS=-mod=readonly + +# Indirect dependencies required via older-than-selected versions must exist in +# the module graph, but do not need to be listed explicitly in the go.mod file +# (since they are implied). +go mod graph +stdout i@v0.1.0 + +# The modules must also appear in the build list, not just the graph. +go list -m all +stdout '^i v0.1.0' + +# The packages provided by those dependencies must resolve. +go list all +stdout '^i$' + +-- go.mod -- +module main + +go 1.13 + +require ( + a v0.0.0 + b v0.0.0 + c v0.0.0 +) + +// Apply replacements so that the test can be self-contained. +// (It's easier to see all of the modules here than to go +// rooting around in testdata/mod.) +replace ( + a => ./a + b => ./b + c => ./c + x v0.1.0 => ./x1 + x v0.2.0 => ./x2 + i => ./i +) +-- main.go -- +package main + +import ( + _ "a" + _ "b" + _ "c" +) + +func main() {} +-- a/go.mod -- +module a +go 1.13 +require x v0.1.0 +-- a/a.go -- +package a +-- b/go.mod -- +module b +go 1.13 +require x v0.2.0 +-- b/b.go -- +package b +-- c/go.mod -- +module c +go 1.13 +-- c/c.go -- +package c +import _ "i" +-- x1/go.mod -- +module x +go1.13 +require i v0.1.0 +-- x2/go.mod -- +module x +go1.13 +-- i/go.mod -- +-- i/i.go -- +package i diff --git a/libgo/go/cmd/go/testdata/script/mod_indirect_main.txt b/libgo/go/cmd/go/testdata/script/mod_indirect_main.txt new file mode 100644 index 00000000000..eeb93f19136 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_indirect_main.txt @@ -0,0 +1,65 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/29773: 'go list -m' was not following +# dependencies through older versions of the main module. + +go list -f '{{with .Module}}{{.Path}}{{with .Version}} {{.}}{{end}}{{end}}' all +cmp stdout pkgmods.txt + +go list -m all +cmp stdout mods.txt + +go mod graph +cmp stdout graph.txt + +-- go.mod -- +module golang.org/issue/root + +go 1.12 + +replace ( + golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0 + golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0 + golang.org/issue/root v0.1.0 => ./root-v0.1.0 +) + +require golang.org/issue/mirror v0.1.0 + +-- root.go -- +package root + +import _ "golang.org/issue/mirror" + +-- mirror-v0.1.0/go.mod -- +module golang.org/issue/mirror + +require golang.org/issue/root v0.1.0 + +-- mirror-v0.1.0/mirror.go -- +package mirror + +import _ "golang.org/issue/pkg" + +-- pkg-v0.1.0/go.mod -- +module golang.org/issue/pkg + +-- pkg-v0.1.0/pkg.go -- +package pkg + +-- root-v0.1.0/go.mod -- +module golang.org/issue/root + +require golang.org/issue/pkg v0.1.0 + +-- pkgmods.txt -- +golang.org/issue/mirror v0.1.0 +golang.org/issue/pkg v0.1.0 +golang.org/issue/root +-- mods.txt -- +golang.org/issue/root +golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0 +golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0 +-- graph.txt -- +golang.org/issue/root golang.org/issue/mirror@v0.1.0 +golang.org/issue/mirror@v0.1.0 golang.org/issue/root@v0.1.0 +golang.org/issue/root@v0.1.0 golang.org/issue/pkg@v0.1.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_indirect_tidy.txt b/libgo/go/cmd/go/testdata/script/mod_indirect_tidy.txt new file mode 100644 index 00000000000..a12b35c72b1 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_indirect_tidy.txt @@ -0,0 +1,60 @@ +env GO111MODULE=on + +# golang.org/issue/31248: loading the build list must not add explicit entries +# for indirect dependencies already implied by older-than-selected versions +# already in the build list. + +cp go.mod.orig go.mod +go mod tidy +cmp go.mod go.mod.orig + +cp go.mod.orig go.mod +go list -m all +cmp go.mod go.mod.orig + +-- go.mod.orig -- +module main + +go 1.13 + +require a v0.0.0 + +replace ( + a v0.0.0 => ./a + b v0.0.0 => ./b + i v0.0.0 => ./i + x v0.1.0 => ./x1 + x v0.2.0 => ./x2 +) +-- main.go -- +package main + +import _ "a" + +func main() {} +-- a/go.mod -- +module a +go 1.13 +require ( + x v0.2.0 + b v0.0.0 +) +-- a/a.go -- +package a +-- b/go.mod -- +module b +go 1.13 +require x v0.1.0 +-- x1/go.mod -- +module x +go 1.13 +require ( + b v0.0.0 + i v0.0.0 +) +-- x2/go.mod -- +module x +go 1.13 +-- i/go.mod -- +module i +go 1.13 diff --git a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt index 2be0d01cce9..76e0b43a735 100644 --- a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt +++ b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt @@ -134,6 +134,19 @@ cd .. go list -m golang.org/x/text stdout 'golang.org/x/text v0.0.0-0.20170915032832-14c0d48ead0c => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' +# A 'replace' directive can replace an invalid 'latest' version, and +# should suppress errors for that version in 'go get -u' +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.999999.0 +go mod edit -replace golang.org/x/text@v1.999999.0=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go get -d golang.org/x/text@upgrade +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999999.0: reading golang.org/x/text/go.mod at revision v1.999999.0: unknown revision v1.999999.0' +cd .. +go get -d golang.org/x/text@upgrade +go list -m golang.org/x/text +stdout 'golang.org/x/text v1.999999.0 => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' + # A pseudo-version derived from a non-ancestor tag is invalid. cp go.mod.orig go.mod go mod edit -require golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c @@ -144,6 +157,16 @@ cd .. ! go list -m golang.org/x/text stderr 'golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)' +# A pseudo-version derived from a canonical tag on the same revision is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag' + # A +incompatible suffix is not allowed on a version that is actually compatible. cp go.mod.orig go.mod go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c+incompatible @@ -165,15 +188,15 @@ go list -m github.com/pierrec/lz4 stdout 'github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1' cd .. -# A +incompatible version for a module that has an explicit go.mod file is invalid. +# A +incompatible pseudo-version for a module that has an explicit go.mod file is invalid. cp go.mod.orig go.mod -go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190131084431-473cd7ce01a1+incompatible +go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d+incompatible cd outside ! go list -m github.com/pierrec/lz4 -stderr 'go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190131084431-473cd7ce01a1\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' +stderr 'go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' cd .. ! go list -m github.com/pierrec/lz4 -stderr 'github.com/pierrec/lz4@v2.0.9-0.20190131084431-473cd7ce01a1\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' +stderr 'github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required' # A +incompatible pseudo-version is valid for a revision of the module # that lacks a go.mod file. diff --git a/libgo/go/cmd/go/testdata/script/mod_list.txt b/libgo/go/cmd/go/testdata/script/mod_list.txt index a15f5bca635..17b33fcc7bf 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list.txt @@ -34,12 +34,12 @@ go list rsc.io/quote/buggy # rsc.io/quote/buggy should not be listable as a module go list -m -e -f '{{.Error.Err}}' nonexist rsc.io/quote/buggy -stdout '^module "nonexist" is not a known dependency' -stdout '^module "rsc.io/quote/buggy" is not a known dependency' +stdout '^module nonexist: not a known dependency$' +stdout '^module rsc.io/quote/buggy: not a known dependency$' ! go list -m nonexist rsc.io/quote/buggy -stderr '^go list -m nonexist: module "nonexist" is not a known dependency' -stderr '^go list -m rsc.io/quote/buggy: module "rsc.io/quote/buggy" is not a known dependency' +stderr '^go list -m: module nonexist: not a known dependency' +stderr '^go list -m: module rsc.io/quote/buggy: not a known dependency' # Module loader does not interfere with list -e (golang.org/issue/24149). go list -e -f '{{.Error.Err}}' database diff --git a/libgo/go/cmd/go/testdata/script/mod_list_compiled_concurrent.txt b/libgo/go/cmd/go/testdata/script/mod_list_compiled_concurrent.txt new file mode 100644 index 00000000000..b08713dcfd7 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_list_compiled_concurrent.txt @@ -0,0 +1,41 @@ +env GO111MODULE=on + +[short] skip + +# Regression test for golang.org/issue/29667: +# spurious 'failed to cache compiled Go files' errors. +# This test failed reliably when run with -count=10 +# on a Linux workstation. + +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & + +wait + +-- go.mod -- +module sandbox/bar +-- bar.go -- +package bar + +import "C" diff --git a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt index c4db0456311..a8023cce9c5 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt @@ -12,9 +12,10 @@ stdout ^math$ go list -f '{{.ImportPath}}' . stdout ^x$ ! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stderr 'unknown import path "rsc.io/quote": cannot find package' +stderr '^can.t load package: package '$WORK'[/\\]gopath/pkg/mod/rsc.io/quote@v1.5.2: can only use path@version syntax with .go get.' + go list -e -f '{{with .Error}}{{.}}{{end}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stdout 'unknown import path "rsc.io/quote": cannot find package' +stdout '^package '$WORK'[/\\]gopath/pkg/mod/rsc.io/quote@v1.5.2: can only use path@version syntax with .go get.' go mod download rsc.io/quote@v1.5.2 go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 stdout '^rsc.io/quote$' diff --git a/libgo/go/cmd/go/testdata/script/mod_list_direct.txt b/libgo/go/cmd/go/testdata/script/mod_list_direct.txt new file mode 100644 index 00000000000..8f858711897 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_list_direct.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +[!net] skip +[!exec:git] skip + +# golang.org/issue/33099: if an import path ends in a major-version suffix, +# ensure that 'direct' mode can resolve the package to the module. +# For a while, (*modfetch.codeRepo).Stat was not checking for a go.mod file, +# which would produce a hard error at the subsequent call to GoMod. + +go list all + +-- go.mod -- +module example.com +go 1.13 + +-- main.go -- +package main + +import _ "vcs-test.golang.org/git/v3pkg.git/v3" + +func main() {} diff --git a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt index 37de8825e06..d43bbe7f2bc 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt @@ -6,7 +6,7 @@ env GO111MODULE=on go mod download ! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stderr 'outside available modules' +stderr 'can only use path@version syntax with .go get.' go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.1 stdout 'rsc.io/quote' diff --git a/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt b/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt index 474df0dc269..f2d06490920 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt @@ -1,8 +1,28 @@ env GO111MODULE=on +# If the current version is not latest, 'go list -u' should include its upgrade. go list -m -u all stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]' +# If the current version is latest, 'go list -u' should omit the upgrade. +go get -d rsc.io/quote@v1.5.2 +go list -m -u all +stdout 'rsc.io/quote v1.5.2$' + +# If the current version is newer than latest, 'go list -u' should +# omit the upgrade. +go get -d rsc.io/quote@v1.5.3-pre1 +go list -m -u all +stdout 'rsc.io/quote v1.5.3-pre1$' + +# If the current build list has a higher version and the user asks about +# a lower one, -u should report the upgrade for the lower one +# but leave the build list unchanged. +go list -m -u rsc.io/quote@v1.5.1 +stdout 'rsc.io/quote v1.5.1 \[v1.5.2\]$' +go list -m -u rsc.io/quote +stdout 'rsc.io/quote v1.5.3-pre1$' + -- go.mod -- module x require rsc.io/quote v1.2.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt b/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt index 6fdf2c7b6be..b97a2e6eaba 100644 --- a/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt +++ b/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt @@ -57,19 +57,29 @@ import ( func Test(t *testing.T) {} -- update-main-expected -- go get: example.com/badchain/c@v1.0.0 updating to - example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong" + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c -- update-a-expected -- go get: example.com/badchain/a@v1.1.0 requires example.com/badchain/b@v1.1.0 requires - example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong" + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c -- list-expected -- go: example.com/badchain/a@v1.1.0 requires example.com/badchain/b@v1.1.0 requires - example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong" + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c -- list-missing-expected -- go: m/use imports - example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong" + example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c -- list-missing-test-expected -- go: m/testuse tested by m/testuse.test imports - example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: unexpected module path "example.com/badchain/wrong" + example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c diff --git a/libgo/go/cmd/go/testdata/script/mod_query.txt b/libgo/go/cmd/go/testdata/script/mod_query.txt index c41f83d264c..e87ca302f0c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_query.txt +++ b/libgo/go/cmd/go/testdata/script/mod_query.txt @@ -22,7 +22,7 @@ go list -m rsc.io/quote@v1.5.3 -stderr 'go list -m rsc.io/quote: no matching versions for query ">v1.5.3"' +stderr 'go list -m: module rsc.io/quote: no matching versions for query ">v1.5.3"' go list -m -e -f '{{.Error.Err}}' rsc.io/quote@>v1.5.3 stdout 'no matching versions for query ">v1.5.3"' diff --git a/libgo/go/cmd/go/testdata/script/mod_query_empty.txt b/libgo/go/cmd/go/testdata/script/mod_query_empty.txt index 4e27c1ee5c8..4d8259b40f1 100644 --- a/libgo/go/cmd/go/testdata/script/mod_query_empty.txt +++ b/libgo/go/cmd/go/testdata/script/mod_query_empty.txt @@ -28,6 +28,20 @@ go list -m example.com/join/... ! stdout 'example.com/join/subpkg' stdout 'example.com/join v1.1.0' +# If the proxy provides an empty @v/list but rejects @latest with +# some other explicit error (for example, a "permission denied" error), +# that error should be reported to the user (and override a successful +# result for other possible module paths). +# +# Depending on how the specific platform enforces permissions, the 'go get' may +# fail either due to the intended permission error or due to a parse error. +# We accept either failure message. +env GOPROXY=file:///$WORK/gatekeeper +chmod 0000 $WORK/gatekeeper/example.com/join/subpkg/@latest +cp go.mod.orig go.mod +! go get -d example.com/join/subpkg +stderr 'go get example.com/join/subpkg: module example.com/join/subpkg: (invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' + -- go.mod.orig -- module example.com/othermodule go 1.13 @@ -50,3 +64,10 @@ v1.0.0-does-not-exist v1.1.0 -- $WORK/notfound/example.com/join/@v/v1.1.0.info -- {"Version": "v1.1.0"} +-- $WORK/gatekeeper/example.com/join/subpkg/@v/list -- +-- $WORK/gatekeeper/example.com/join/subpkg/@latest -- +ERROR: Latest version is forbidden. +-- $WORK/gatekeeper/example.com/join/@v/list -- +v1.1.0 +-- $WORK/gatekeeper/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb.txt index 8e1f3d7a7b3..641b9e73bcc 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb.txt @@ -9,8 +9,8 @@ env dbname=localhost.localdev/sumdb cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-wrong ! go get -d rsc.io/quote -stderr 'verifying rsc.io/quote@v1.5.2/go.mod: checksum mismatch' -stderr 'downloaded: h1:LzX7' +stderr 'verifying rsc.io/quote@v1.5.2: checksum mismatch' +stderr 'downloaded: h1:3fEy' stderr 'localhost.localdev/sumdb: h1:wrong' stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.' ! go get -d rsc.io/sampler diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt index a44a87499a3..486bdf5ecf6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt @@ -28,7 +28,7 @@ cp go.mod.orig go.mod rm go.sum env GOPROXY=off go get -d rsc.io/quote@v1.5.2 # using cache -rm $GOPATH/pkg/mod/download/cache/sumdb/localhost.localdev/sumdb/lookup/rsc.io/quote@v1.5.2 +rm $GOPATH/pkg/mod/cache/download/sumdb/localhost.localdev/sumdb/lookup/rsc.io/quote@v1.5.2 go get -d rsc.io/quote@v1.5.2 # using go.sum # fetch fails once we lose access to both cache and go.sum diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt index 744632ec904..47c8a3a0f3c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt @@ -2,6 +2,7 @@ env GO111MODULE=on env GOSUMDB= +env GOPATH=$WORK/gopath1 # With a file-based proxy with an empty checksum directory, # downloading a new module should fail, even if a subsequent @@ -18,11 +19,20 @@ stderr '^verifying golang.org/x/text.*: Not Found' [!windows] env GOPROXY=file://$WORK/emptyproxy,https://proxy.golang.org go get -d golang.org/x/text@v0.3.2 +# After a successful sumdb lookup, the lookup can be repeated +# using the download cache as a proxy. +cp supported $GOPATH/pkg/mod/cache/download/sumdb/sum.golang.org/supported +[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download,file:///$WORK/sumproxy +[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download,file://$WORK/sumproxy +env GOPATH=$WORK/gopath2 +rm go.sum +go get -d -x -v golang.org/x/text@v0.3.2 + # Once the checksum is present in the go.sum file, # an empty file-based sumdb can be used in conjunction with # a fallback module mirror. grep golang.org/x/text go.sum -go clean -modcache +env GOPATH=$WORK/gopath3 [windows] env GOPROXY=file:///$WORK/sumproxy [!windows] env GOPROXY=file://$WORK/sumproxy ! go get -d golang.org/x/text@v0.3.2 @@ -30,6 +40,8 @@ go clean -modcache [!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org go get -d golang.org/x/text@v0.3.2 +-- supported -- + -- go.mod -- module example.com go 1.13 diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt index 964501f2ee3..40a07fc7e9f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt @@ -14,31 +14,39 @@ stdout '^sum.golang.org$' [!exec:git] skip env GOSUMDB=sum.golang.org env GOPROXY=direct -go get -d rsc.io/quote +go get -d rsc.io/quote@v1.5.2 +cp go.sum saved.sum # download from proxy.golang.org with go.sum entry already go clean -modcache env GOSUMDB= env GOPROXY= -go get -x -d rsc.io/quote +go get -x -d rsc.io/quote@v1.5.2 ! stderr github stderr proxy.golang.org/rsc.io/quote ! stderr sum.golang.org/tile ! stderr sum.golang.org/lookup/rsc.io/quote +cmp go.sum saved.sum -# download again, using checksum database to validate new go.sum lines +# Download again. +# Should use the checksum database to validate new go.sum lines, +# but not need to fetch any new data from the proxy. rm go.sum -go get -x -d rsc.io/quote +go get -x -d rsc.io/quote@v1.5.2 ! stderr github -stderr proxy.golang.org/rsc.io/quote +! stderr proxy.golang.org/rsc.io/quote stderr sum.golang.org/tile stderr sum.golang.org/lookup/rsc.io/quote +cmp go.sum saved.sum # test fallback to direct env TESTGOPROXY404=1 -go get -x -d rsc.io/quote +go clean -modcache +rm go.sum +go get -x -d rsc.io/quote@v1.5.2 stderr 'proxy.golang.org.*404 testing' stderr github.com/rsc +cmp go.sum saved.sum -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt index 6fbf7aeb8a9..28166913fd5 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt @@ -6,14 +6,14 @@ env GOPROXY GONOPROXY GOSUMDB GONOSUMDB # basic fetch (through proxy) works cp go.mod.orig go.mod go get -d rsc.io/fortune@v1.0.0 # note: must use test proxy, does not exist in real world -rm $GOPATH/pkg/mod/download/cache/sumdb # rm sumdb cache but NOT package download cache +rm $GOPATH/pkg/mod/cache/download/sumdb # rm sumdb cache but NOT package download cache rm go.sum # can fetch by explicit URL cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-direct go get -d rsc.io/fortune@v1.0.0 -rm $GOPATH/pkg/mod/download/cache/sumdb +rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum # direct access fails (because localhost.localdev does not exist) @@ -25,7 +25,7 @@ env GOSUMDB=$sumdb env GOPROXY=direct ! go get -d rsc.io/fortune@v1.0.0 stderr 'verifying.*localhost.localdev' -rm $GOPATH/pkg/mod/download/cache/sumdb +rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum # proxy 404 falls back to direct access (which fails) @@ -34,7 +34,7 @@ env GOSUMDB=$sumdb env GOPROXY=$proxy/sumdb-404 ! go get -d rsc.io/fortune@v1.0.0 stderr 'verifying.*localhost.localdev' -rm $GOPATH/pkg/mod/download/cache/sumdb +rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum # proxy non-200/404/410 stops direct access @@ -43,7 +43,7 @@ env GOSUMDB=$sumdb env GOPROXY=$proxy/sumdb-503 ! go get -d rsc.io/fortune@v1.0.0 stderr '503 Service Unavailable' -rm $GOPATH/pkg/mod/download/cache/sumdb +rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum -- go.mod.orig -- diff --git a/libgo/go/cmd/go/testdata/script/mod_test_cached.txt b/libgo/go/cmd/go/testdata/script/mod_test_cached.txt new file mode 100644 index 00000000000..ffd573c02a9 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_test_cached.txt @@ -0,0 +1,77 @@ +[short] skip + +env GO111MODULE=on +env GOCACHE=$WORK/gocache +env GODEBUG=gocachetest=1 + +# The first run of a test should not be cached. +# The second run should be. +go test -run=WriteTmp . +! stdout '(cached)' +go test -run=WriteTmp . +stdout '(cached)' + +# 'go test' without arguments should never be cached. +go test -run=WriteTmp +! stdout '(cached)' +go test -run=WriteTmp +! stdout '(cached)' + +# We should never cache a test run from command-line files. +go test -run=WriteTmp ./foo_test.go +! stdout '(cached)' +go test -run=WriteTmp ./foo_test.go +! stdout '(cached)' + +[!exec:sleep] stop +# The go command refuses to cache access to files younger than 2s, so sleep that long. +exec sleep 2 + +# Touching a file that the test reads from within its testdata should invalidate the cache. +go test -run=ReadTestdata . +! stdout '(cached)' +go test -run=ReadTestdata . +stdout '(cached)' +cp testdata/bar.txt testdata/foo.txt +go test -run=ReadTestdata . +! stdout '(cached)' + +-- go.mod -- +module golang.org/issue/29111/foo + +-- foo.go -- +package foo + +-- testdata/foo.txt -- +foo +-- testdata/bar.txt -- +bar + +-- foo_test.go -- +package foo_test + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestWriteTmp(t *testing.T) { + dir, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + err = ioutil.WriteFile(filepath.Join(dir, "x"), nil, 0666) + if err != nil { + t.Fatal(err) + } +} + +func TestReadTestdata(t *testing.T) { + _, err := ioutil.ReadFile("testdata/foo.txt") + if err != nil { + t.Fatal(err) + } +} diff --git a/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt b/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt new file mode 100644 index 00000000000..9bb8528cb0b --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt @@ -0,0 +1,39 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/27063: +# 'go mod tidy' and 'go mod vendor' should not hide loading errors. + +! go mod tidy +stderr '^issue27063 imports\n\tnonexist: malformed module path "nonexist": missing dot in first path element' +stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' +stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' + +! go mod vendor +stderr '^issue27063 imports\n\tnonexist: malformed module path "nonexist": missing dot in first path element' +stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' +stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' + +-- go.mod -- +module issue27063 + +go 1.13 + +require issue27063/other v0.0.0 +replace issue27063/other => ./other +-- x.go -- +package main + +import ( + "nonexist" + + "nonexist.example.com" + "issue27063/other" +) + +func main() {} +-- other/go.mod -- +module issue27063/other +-- other/other.go -- +package other + +import "other.example.com/nonexist" diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor.txt b/libgo/go/cmd/go/testdata/script/mod_vendor.txt index eae4f2946ce..5d872c3c80e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vendor.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vendor.txt @@ -171,12 +171,6 @@ package m import _ "appengine" import _ "appengine/datastore" --- nonexistent.go -- -// +build alternatereality - -package m - -import _ "nonexistent.rsc.io" -- mypkg/go.mod -- module me -- mypkg/mydir/d.go -- diff --git a/libgo/go/cmd/go/testdata/script/test_go111module_cache.txt b/libgo/go/cmd/go/testdata/script/test_go111module_cache.txt new file mode 100644 index 00000000000..ca1de43a2b5 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_go111module_cache.txt @@ -0,0 +1,15 @@ +env GO111MODULE=on +go mod init foo +go test +stdout ^ok\s+foo +env GO111MODULE=off +go test +stdout ^ok\s+ +! stdout ^ok\s+(cache)$ + +-- main_test.go -- +package main + +import "testing" + +func TestF(t *testing.T) {} diff --git a/libgo/go/cmd/go/testdata/script/test_init.txt b/libgo/go/cmd/go/testdata/script/test_init.txt deleted file mode 100644 index 73b4f3c7686..00000000000 --- a/libgo/go/cmd/go/testdata/script/test_init.txt +++ /dev/null @@ -1,86 +0,0 @@ -# Tests for automatic testing.Init calls when using 'go test'. - -env GO111MODULE=on - -# A TestMain should be able to access testing flags if it calls flag.Parse -# without needing to use testing.Init. -# Test code can use the name 'testing' without colliding with generated -# testinginit code. -# Tests running under 'go test' should observe that testing.Init is called -# before any user package initialization code runs. -go test -stdout TestMain -stdout TestInit -stdout TestExt - --- go.mod -- -module m - --- init_test.go -- -package testinitflag - -import ( - "flag" - "fmt" - "os" - Testing "testing" -) - -func testFlagsInitialized() bool { - found := false - flag.VisitAll(func(f *flag.Flag) { - if f.Name == "test.count" { - found = true - } - }) - return found -} - -var testing int -var testingInitAtInitialization = testFlagsInitialized() - -func TestInit(t *Testing.T) { - if !testingInitAtInitialization { - t.Fatal("testing.Init not called before package initialization") - } - fmt.Printf("TestInit\n") -} - -func TestMain(m *Testing.M) { - fmt.Printf("TestMain\n") - flag.Parse() - if !testFlagsInitialized() { - fmt.Println("testing flags not registered") - os.Exit(1) - } - os.Exit(m.Run()) -} - --- external_test.go -- -package testinitflag_test - -import ( - "flag" - "fmt" - Testing "testing" -) - -func testFlagsInitialized() bool { - found := false - flag.VisitAll(func(f *flag.Flag) { - if f.Name == "test.count" { - found = true - } - }) - return found -} - -var testing int -var testingInitAtInitialization = testFlagsInitialized() - -func TestExt(t *Testing.T) { - fmt.Printf("TestExt\n") - if !testingInitAtInitialization { - t.Fatal("testing.Init not called before package initialization") - } -} diff --git a/libgo/go/cmd/go/testdata/script/version.txt b/libgo/go/cmd/go/testdata/script/version.txt index cb4881f7a72..9086f047e4b 100644 --- a/libgo/go/cmd/go/testdata/script/version.txt +++ b/libgo/go/cmd/go/testdata/script/version.txt @@ -8,5 +8,12 @@ go version -m fortune.exe stdout '^\tpath\trsc.io/fortune' stdout '^\tmod\trsc.io/fortune\tv1.0.0' +go build -buildmode=pie -o external.exe rsc.io/fortune +go version external.exe +stdout '^external.exe: .+' +go version -m external.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go b/libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go new file mode 100644 index 00000000000..a59555bb61d --- /dev/null +++ b/libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go @@ -0,0 +1,29 @@ +// Copyright 2019 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. + +package standalone_testmain_flag_test + +import ( + "flag" + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + // A TestMain should be able to access testing flags if it calls + // flag.Parse without needing to use testing.Init. + flag.Parse() + found := false + flag.VisitAll(func(f *flag.Flag) { + if f.Name == "test.count" { + found = true + } + }) + if !found { + fmt.Println("testing flags not registered") + os.Exit(1) + } + os.Exit(m.Run()) +} diff --git a/libgo/go/cmd/gofmt/testdata/go2numbers.golden b/libgo/go/cmd/gofmt/testdata/go2numbers.golden new file mode 100644 index 00000000000..0184aaa6ced --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/go2numbers.golden @@ -0,0 +1,186 @@ +package p + +const ( + // 0-octals + _ = 0 + _ = 0123 + _ = 0123456 + + _ = 0_123 + _ = 0123_456 + + // decimals + _ = 1 + _ = 1234 + _ = 1234567 + + _ = 1_234 + _ = 1_234_567 + + // hexadecimals + _ = 0x0 + _ = 0x1234 + _ = 0xcafef00d + + _ = 0x0 + _ = 0x1234 + _ = 0xCAFEf00d + + _ = 0x_0 + _ = 0x_1234 + _ = 0x_CAFE_f00d + + // octals + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + // binaries + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0b_0 + _ = 0b10_11 + _ = 0b_0010_1101 + + // decimal floats + _ = 0. + _ = 123. + _ = 0123. + + _ = .0 + _ = .123 + _ = .0123 + + _ = 0e0 + _ = 123e+0 + _ = 0123e-1 + + _ = 0e-0 + _ = 123e+0 + _ = 0123e123 + + _ = 0.e+1 + _ = 123.e-10 + _ = 0123.e123 + + _ = .0e-1 + _ = .123e+10 + _ = .0123e123 + + _ = 0.0 + _ = 123.123 + _ = 0123.0123 + + _ = 0.0e1 + _ = 123.123e-10 + _ = 0123.0123e+456 + + _ = 1_2_3. + _ = 0_123. + + _ = 0_0e0 + _ = 1_2_3e0 + _ = 0_123e0 + + _ = 0e-0_0 + _ = 1_2_3e+0 + _ = 0123e1_2_3 + + _ = 0.e+1 + _ = 123.e-1_0 + _ = 01_23.e123 + + _ = .0e-1 + _ = .123e+10 + _ = .0123e123 + + _ = 1_2_3.123 + _ = 0123.01_23 + + // hexadecimal floats + _ = 0x0.p+0 + _ = 0xdeadcafe.p-10 + _ = 0x1234.p123 + + _ = 0x.1p-0 + _ = 0x.deadcafep2 + _ = 0x.1234p+10 + + _ = 0x0p0 + _ = 0xdeadcafep+1 + _ = 0x1234p-10 + + _ = 0x0.0p0 + _ = 0xdead.cafep+1 + _ = 0x12.34p-10 + + _ = 0xdead_cafep+1 + _ = 0x_1234p-10 + + _ = 0x_dead_cafe.p-10 + _ = 0x12_34.p1_2_3 + _ = 0x1_2_3_4.p-1_2_3 + + // imaginaries + _ = 0i + _ = 0i + _ = 8i + _ = 0i + _ = 123i + _ = 123i + _ = 56789i + _ = 1234i + _ = 1234567i + + _ = 0i + _ = 0i + _ = 8i + _ = 0i + _ = 123i + _ = 123i + _ = 56_789i + _ = 1_234i + _ = 1_234_567i + + _ = 0.i + _ = 123.i + _ = 0123.i + _ = 000123.i + + _ = 0e0i + _ = 123e0i + _ = 0123e0i + _ = 000123e0i + + _ = 0.e+1i + _ = 123.e-1_0i + _ = 01_23.e123i + _ = 00_01_23.e123i + + _ = 0b1010i + _ = 0b1010i + _ = 0o660i + _ = 0o660i + _ = 0xabcDEFi + _ = 0xabcDEFi + _ = 0xabcDEFp0i + _ = 0xabcDEFp0i +) diff --git a/libgo/go/cmd/gofmt/testdata/go2numbers.input b/libgo/go/cmd/gofmt/testdata/go2numbers.input new file mode 100644 index 00000000000..f3e7828d948 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/go2numbers.input @@ -0,0 +1,186 @@ +package p + +const ( + // 0-octals + _ = 0 + _ = 0123 + _ = 0123456 + + _ = 0_123 + _ = 0123_456 + + // decimals + _ = 1 + _ = 1234 + _ = 1234567 + + _ = 1_234 + _ = 1_234_567 + + // hexadecimals + _ = 0x0 + _ = 0x1234 + _ = 0xcafef00d + + _ = 0X0 + _ = 0X1234 + _ = 0XCAFEf00d + + _ = 0X_0 + _ = 0X_1234 + _ = 0X_CAFE_f00d + + // octals + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0O0 + _ = 0O1234 + _ = 0O01234567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + _ = 0O_0 + _ = 0O_1234 + _ = 0O0123_4567 + + // binaries + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0B0 + _ = 0B1011 + _ = 0B00101101 + + _ = 0b_0 + _ = 0b10_11 + _ = 0b_0010_1101 + + // decimal floats + _ = 0. + _ = 123. + _ = 0123. + + _ = .0 + _ = .123 + _ = .0123 + + _ = 0e0 + _ = 123e+0 + _ = 0123E-1 + + _ = 0e-0 + _ = 123E+0 + _ = 0123E123 + + _ = 0.e+1 + _ = 123.E-10 + _ = 0123.e123 + + _ = .0e-1 + _ = .123E+10 + _ = .0123E123 + + _ = 0.0 + _ = 123.123 + _ = 0123.0123 + + _ = 0.0e1 + _ = 123.123E-10 + _ = 0123.0123e+456 + + _ = 1_2_3. + _ = 0_123. + + _ = 0_0e0 + _ = 1_2_3e0 + _ = 0_123e0 + + _ = 0e-0_0 + _ = 1_2_3E+0 + _ = 0123E1_2_3 + + _ = 0.e+1 + _ = 123.E-1_0 + _ = 01_23.e123 + + _ = .0e-1 + _ = .123E+10 + _ = .0123E123 + + _ = 1_2_3.123 + _ = 0123.01_23 + + // hexadecimal floats + _ = 0x0.p+0 + _ = 0Xdeadcafe.p-10 + _ = 0x1234.P123 + + _ = 0x.1p-0 + _ = 0X.deadcafep2 + _ = 0x.1234P+10 + + _ = 0x0p0 + _ = 0Xdeadcafep+1 + _ = 0x1234P-10 + + _ = 0x0.0p0 + _ = 0Xdead.cafep+1 + _ = 0x12.34P-10 + + _ = 0Xdead_cafep+1 + _ = 0x_1234P-10 + + _ = 0X_dead_cafe.p-10 + _ = 0x12_34.P1_2_3 + _ = 0X1_2_3_4.P-1_2_3 + + // imaginaries + _ = 0i + _ = 00i + _ = 08i + _ = 0000000000i + _ = 0123i + _ = 0000000123i + _ = 0000056789i + _ = 1234i + _ = 1234567i + + _ = 0i + _ = 0_0i + _ = 0_8i + _ = 0_000_000_000i + _ = 0_123i + _ = 0_000_000_123i + _ = 0_000_056_789i + _ = 1_234i + _ = 1_234_567i + + _ = 0.i + _ = 123.i + _ = 0123.i + _ = 000123.i + + _ = 0e0i + _ = 123e0i + _ = 0123E0i + _ = 000123E0i + + _ = 0.e+1i + _ = 123.E-1_0i + _ = 01_23.e123i + _ = 00_01_23.e123i + + _ = 0b1010i + _ = 0B1010i + _ = 0o660i + _ = 0O660i + _ = 0xabcDEFi + _ = 0XabcDEFi + _ = 0xabcDEFP0i + _ = 0XabcDEFp0i +) diff --git a/libgo/go/cmd/gofmt/testdata/import.golden b/libgo/go/cmd/gofmt/testdata/import.golden index 51d7be79dfa..29bdc9baf4a 100644 --- a/libgo/go/cmd/gofmt/testdata/import.golden +++ b/libgo/go/cmd/gofmt/testdata/import.golden @@ -8,6 +8,11 @@ import ( "math" ) +import ( + "fmt" + "math" +) + import ( "fmt" diff --git a/libgo/go/cmd/gofmt/testdata/import.input b/libgo/go/cmd/gofmt/testdata/import.input index 9a4b09dbf91..78ab4f65443 100644 --- a/libgo/go/cmd/gofmt/testdata/import.input +++ b/libgo/go/cmd/gofmt/testdata/import.input @@ -8,6 +8,9 @@ import ( "io" ) +import("fmt" +"math") + import ( "fmt" diff --git a/libgo/go/cmd/gofmt/testdata/rewrite9.golden b/libgo/go/cmd/gofmt/testdata/rewrite9.golden new file mode 100644 index 00000000000..fffbd3d05ba --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/rewrite9.golden @@ -0,0 +1,11 @@ +//gofmt -r=a&&b!=2->a + +// Copyright 2017 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. + +// Issue 18987. + +package p + +const _ = x != 1 diff --git a/libgo/go/cmd/gofmt/testdata/rewrite9.input b/libgo/go/cmd/gofmt/testdata/rewrite9.input new file mode 100644 index 00000000000..106ad94bc52 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/rewrite9.input @@ -0,0 +1,11 @@ +//gofmt -r=a&&b!=2->a + +// Copyright 2017 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. + +// Issue 18987. + +package p + +const _ = x != 1 && x != 2 diff --git a/libgo/go/cmd/gofmt/testdata/typealias.golden b/libgo/go/cmd/gofmt/testdata/typealias.golden new file mode 100644 index 00000000000..bbbbf321214 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/typealias.golden @@ -0,0 +1,24 @@ +package q + +import "p" + +type _ = int +type a = struct{ x int } +type b = p.B + +type ( + _ = chan<- int + aa = interface{} + bb = p.BB +) + +// TODO(gri) We may want to put the '=' into a separate column if +// we have mixed (regular and alias) type declarations in a group. +type ( + _ chan<- int + _ = chan<- int + aa0 interface{} + aaa = interface{} + bb0 p.BB + bbb = p.BB +) diff --git a/libgo/go/cmd/gofmt/testdata/typealias.input b/libgo/go/cmd/gofmt/testdata/typealias.input new file mode 100644 index 00000000000..6e49328e346 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/typealias.input @@ -0,0 +1,24 @@ +package q + +import "p" + +type _ = int +type a = struct{ x int } +type b = p.B + +type ( + _ = chan<- int + aa = interface{} + bb = p.BB +) + +// TODO(gri) We may want to put the '=' into a separate column if +// we have mixed (regular and alias) type declarations in a group. +type ( + _ chan<- int + _ = chan<- int + aa0 interface{} + aaa = interface{} + bb0 p.BB + bbb = p.BB +) diff --git a/libgo/go/cmd/internal/objabi/flag.go b/libgo/go/cmd/internal/objabi/flag.go index 90e944656bb..79ad2ccf748 100644 --- a/libgo/go/cmd/internal/objabi/flag.go +++ b/libgo/go/cmd/internal/objabi/flag.go @@ -86,6 +86,10 @@ func (versionFlag) Set(s string) error { name = name[strings.LastIndex(name, `/`)+1:] name = name[strings.LastIndex(name, `\`)+1:] name = strings.TrimSuffix(name, ".exe") + + // If there's an active experiment, include that, + // to distinguish go1.10.2 with an experiment + // from go1.10.2 without an experiment. p := Expstring() if p == DefaultExpstring() { p = "" @@ -101,12 +105,6 @@ func (versionFlag) Set(s string) error { // build ID of the binary, so that if the compiler is changed and // rebuilt, we notice and rebuild all packages. if s == "full" { - // If there's an active experiment, include that, - // to distinguish go1.10.2 with an experiment - // from go1.10.2 without an experiment. - if x := Expstring(); x != "" { - p += " " + x - } if strings.HasPrefix(Version, "devel") { p += " buildID=" + buildID } diff --git a/libgo/go/context/context.go b/libgo/go/context/context.go index 05d01d0294a..62590850a66 100644 --- a/libgo/go/context/context.go +++ b/libgo/go/context/context.go @@ -49,7 +49,6 @@ package context import ( "errors" - "internal/oserror" "internal/reflectlite" "sync" "time" @@ -163,9 +162,6 @@ type deadlineExceededError struct{} func (deadlineExceededError) Error() string { return "context deadline exceeded" } func (deadlineExceededError) Timeout() bool { return true } func (deadlineExceededError) Temporary() bool { return true } -func (deadlineExceededError) Is(target error) bool { - return target == oserror.ErrTimeout || target == oserror.ErrTemporary -} // An emptyCtx is never canceled, has no values, and has no deadline. It is not // struct{}, since vars of this type must have distinct addresses. diff --git a/libgo/go/context/context_test.go b/libgo/go/context/context_test.go index 96ad14627c3..b07a5cfce64 100644 --- a/libgo/go/context/context_test.go +++ b/libgo/go/context/context_test.go @@ -5,10 +5,8 @@ package context import ( - "errors" "fmt" "math/rand" - "os" "runtime" "strings" "sync" @@ -649,7 +647,4 @@ func XTestDeadlineExceededSupportsTimeout(t testingT) { if !i.Timeout() { t.Fatal("wrong value for timeout") } - if !errors.Is(DeadlineExceeded, os.ErrTimeout) { - t.Fatal("errors.Is(DeadlineExceeded, os.ErrTimeout) = false, want true") - } } diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index ad32d3e3add..d058949242d 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -555,7 +555,7 @@ func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int } // DecryptOAEP decrypts ciphertext using RSA-OAEP. - +// // OAEP is parameterised by a hash function that is used as a random oracle. // Encryption and decryption of a given message must use the same hash function // and sha256.New() is a reasonable choice. diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go index d135b1fc994..ef0b3858487 100644 --- a/libgo/go/crypto/tls/common.go +++ b/libgo/go/crypto/tls/common.go @@ -23,11 +23,14 @@ import ( ) const ( - VersionSSL30 = 0x0300 VersionTLS10 = 0x0301 VersionTLS11 = 0x0302 VersionTLS12 = 0x0303 VersionTLS13 = 0x0304 + + // Deprecated: SSLv3 is cryptographically broken, and will be + // removed in Go 1.14. See golang.org/issue/32716. + VersionSSL30 = 0x0300 ) const ( @@ -791,6 +794,10 @@ var supportedVersions = []uint16{ func (c *Config) supportedVersions(isClient bool) []uint16 { versions := make([]uint16, 0, len(supportedVersions)) for _, v := range supportedVersions { + // TLS 1.0 is the default minimum version. + if (c == nil || c.MinVersion == 0) && v < VersionTLS10 { + continue + } if c != nil && c.MinVersion != 0 && v < c.MinVersion { continue } diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index 22b126fa22d..a9c1c08cbc4 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -77,6 +77,20 @@ func TestRejectBadProtocolVersion(t *testing.T) { }, "unsupported versions") } +func TestSSLv3OptIn(t *testing.T) { + config := testConfig.Clone() + config.MinVersion = 0 + testClientHelloFailure(t, config, &clientHelloMsg{ + vers: VersionSSL30, + random: make([]byte, 32), + }, "unsupported versions") + testClientHelloFailure(t, config, &clientHelloMsg{ + vers: VersionTLS12, + supportedVersions: []uint16{VersionSSL30}, + random: make([]byte, 32), + }, "unsupported versions") +} + func TestNoSuiteOverlap(t *testing.T) { clientHello := &clientHelloMsg{ vers: VersionTLS10, diff --git a/libgo/go/crypto/tls/handshake_test.go b/libgo/go/crypto/tls/handshake_test.go index 35c1fe8bf58..cfd92908a96 100644 --- a/libgo/go/crypto/tls/handshake_test.go +++ b/libgo/go/crypto/tls/handshake_test.go @@ -222,28 +222,65 @@ func tempFile(contents string) string { // localListener is set up by TestMain and used by localPipe to create Conn // pairs like net.Pipe, but connected by an actual buffered TCP connection. var localListener struct { - sync.Mutex - net.Listener + mu sync.Mutex + addr net.Addr + ch chan net.Conn +} + +const localFlakes = 0 // change to 1 or 2 to exercise localServer/localPipe handling of mismatches + +func localServer(l net.Listener) { + for n := 0; ; n++ { + c, err := l.Accept() + if err != nil { + return + } + if localFlakes == 1 && n%2 == 0 { + c.Close() + continue + } + localListener.ch <- c + } } func localPipe(t testing.TB) (net.Conn, net.Conn) { - localListener.Lock() - defer localListener.Unlock() - c := make(chan net.Conn) - go func() { - conn, err := localListener.Accept() + localListener.mu.Lock() + defer localListener.mu.Unlock() + + addr := localListener.addr + +Dialing: + // We expect a rare mismatch, but probably not 5 in a row. + for i := 0; i < 5; i++ { + tooSlow := time.NewTimer(1 * time.Second) + defer tooSlow.Stop() + c1, err := net.Dial(addr.Network(), addr.String()) if err != nil { - t.Errorf("Failed to accept local connection: %v", err) + t.Fatalf("localPipe: %v", err) + } + if localFlakes == 2 && i == 0 { + c1.Close() + continue + } + for { + select { + case <-tooSlow.C: + t.Logf("localPipe: timeout waiting for %v", c1.LocalAddr()) + c1.Close() + continue Dialing + + case c2 := <-localListener.ch: + if c2.RemoteAddr().String() == c1.LocalAddr().String() { + return c1, c2 + } + t.Logf("localPipe: unexpected connection: %v != %v", c2.RemoteAddr(), c1.LocalAddr()) + c2.Close() + } } - c <- conn - }() - addr := localListener.Addr() - c1, err := net.Dial(addr.Network(), addr.String()) - if err != nil { - t.Fatalf("Failed to dial local connection: %v", err) } - c2 := <-c - return c1, c2 + + t.Fatalf("localPipe: failed to connect") + panic("unreachable") } // zeroSource is an io.Reader that returns an unlimited number of zero bytes. @@ -293,8 +330,10 @@ func runMain(m *testing.M) int { fmt.Fprintf(os.Stderr, "Failed to open local listener: %v", err) os.Exit(1) } - localListener.Listener = l - defer localListener.Close() + localListener.ch = make(chan net.Conn) + localListener.addr = l.Addr() + defer l.Close() + go localServer(l) if err := checkOpenSSLVersion(); err != nil { fmt.Fprintf(os.Stderr, "Error: %v", err) diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go index a07727c92bf..b68c074855f 100644 --- a/libgo/go/crypto/tls/tls_test.go +++ b/libgo/go/crypto/tls/tls_test.go @@ -359,50 +359,6 @@ func TestVerifyHostname(t *testing.T) { } } -func TestVerifyHostnameResumed(t *testing.T) { - t.Run("TLSv12", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS12) }) - t.Run("TLSv13", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS13) }) -} - -func testVerifyHostnameResumed(t *testing.T, version uint16) { - testenv.MustHaveExternalNetwork(t) - - config := &Config{ - MaxVersion: version, - ClientSessionCache: NewLRUClientSessionCache(32), - } - for i := 0; i < 2; i++ { - c, err := DialWithDialer(&net.Dialer{ - Timeout: 10 * time.Second, - }, "tcp", "mail.google.com:https", config) - if err != nil { - t.Fatalf("Dial #%d: %v", i, err) - } - cs := c.ConnectionState() - if i > 0 && !cs.DidResume { - t.Fatalf("Subsequent connection unexpectedly didn't resume") - } - if cs.Version != version { - t.Fatalf("Unexpectedly negotiated version %x", cs.Version) - } - if cs.VerifiedChains == nil { - t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i) - } - if err := c.VerifyHostname("mail.google.com"); err != nil { - t.Fatalf("verify mail.google.com #%d: %v", i, err) - } - // Have the server send some data so session tickets are delivered. - c.SetDeadline(time.Now().Add(5 * time.Second)) - if _, err := io.WriteString(c, "HEAD / HTTP/1.0\n\n"); err != nil { - t.Fatal(err) - } - if _, err := c.Read(make([]byte, 1)); err != nil { - t.Fatal(err) - } - c.Close() - } -} - func TestConnCloseBreakingWrite(t *testing.T) { ln := newLocalListener(t) defer ln.Close() diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index 1a5424f54e8..e2a58203d9d 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -171,6 +171,11 @@ type Symbol struct { Info, Other byte Section SectionIndex Value, Size uint64 + + // Version and Library are present only for the dynamic symbol + // table. + Version string + Library string } /* @@ -1321,12 +1326,23 @@ func (f *File) Symbols() ([]Symbol, error) { // DynamicSymbols returns the dynamic symbol table for f. The symbols // will be listed in the order they appear in f. // +// If f has a symbol version table, the returned Symbols will have +// initialized Version and Library fields. +// // For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0. // After retrieving the symbols as symtab, an externally supplied index x // corresponds to symtab[x-1], not symtab[x]. func (f *File) DynamicSymbols() ([]Symbol, error) { - sym, _, err := f.getSymbols(SHT_DYNSYM) - return sym, err + sym, str, err := f.getSymbols(SHT_DYNSYM) + if err != nil { + return nil, err + } + if f.gnuVersionInit(str) { + for i := range sym { + sym[i].Library, sym[i].Version = f.gnuVersion(i) + } + } + return sym, nil } type ImportedSymbol struct { @@ -1349,7 +1365,8 @@ func (f *File) ImportedSymbols() ([]ImportedSymbol, error) { for i, s := range sym { if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF { all = append(all, ImportedSymbol{Name: s.Name}) - f.gnuVersion(i, &all[len(all)-1]) + sym := &all[len(all)-1] + sym.Library, sym.Version = f.gnuVersion(i) } } return all, nil @@ -1362,11 +1379,16 @@ type verneed struct { // gnuVersionInit parses the GNU version tables // for use by calls to gnuVersion. -func (f *File) gnuVersionInit(str []byte) { +func (f *File) gnuVersionInit(str []byte) bool { + if f.gnuNeed != nil { + // Already initialized + return true + } + // Accumulate verneed information. vn := f.SectionByType(SHT_GNU_VERNEED) if vn == nil { - return + return false } d, _ := vn.Data() @@ -1421,17 +1443,18 @@ func (f *File) gnuVersionInit(str []byte) { // Versym parallels symbol table, indexing into verneed. vs := f.SectionByType(SHT_GNU_VERSYM) if vs == nil { - return + return false } d, _ = vs.Data() f.gnuNeed = need f.gnuVersym = d + return true } // gnuVersion adds Library and Version information to sym, // which came from offset i of the symbol table. -func (f *File) gnuVersion(i int, sym *ImportedSymbol) { +func (f *File) gnuVersion(i int) (library string, version string) { // Each entry is two bytes. i = (i + 1) * 2 if i >= len(f.gnuVersym) { @@ -1442,8 +1465,7 @@ func (f *File) gnuVersion(i int, sym *ImportedSymbol) { return } n := &f.gnuNeed[j] - sym.Library = n.File - sym.Version = n.Name + return n.File, n.Name } // ImportedLibraries returns the names of all libraries diff --git a/libgo/go/debug/elf/symbols_test.go b/libgo/go/debug/elf/symbols_test.go index 1b79520e3cc..42f02312e87 100644 --- a/libgo/go/debug/elf/symbols_test.go +++ b/libgo/go/debug/elf/symbols_test.go @@ -819,6 +819,8 @@ var dynamicSymbolsGolden = map[string][]Symbol{ Section: 0x0, Value: 0x0, Size: 0x18C, + Version: "GLIBC_2.2.5", + Library: "libc.so.6", }, Symbol{ Name: "__libc_start_main", @@ -827,6 +829,8 @@ var dynamicSymbolsGolden = map[string][]Symbol{ Section: 0x0, Value: 0x0, Size: 0x1C2, + Version: "GLIBC_2.2.5", + Library: "libc.so.6", }, }, "testdata/go-relocation-test-clang-x86.obj": {}, diff --git a/libgo/go/encoding/csv/writer.go b/libgo/go/encoding/csv/writer.go index b18996a930d..3f34bc51dbf 100644 --- a/libgo/go/encoding/csv/writer.go +++ b/libgo/go/encoding/csv/writer.go @@ -41,7 +41,7 @@ func NewWriter(w io.Writer) *Writer { } } -// Writer writes a single CSV record to w along with any necessary quoting. +// Write writes a single CSV record to w along with any necessary quoting. // A record is a slice of strings with each string being one field. // Writes are buffered, so Flush must eventually be called to ensure // that the record is written to the underlying io.Writer. diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index bdd94e34ce6..cbd71acfc6c 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -272,9 +272,6 @@ type decodeState struct { savedError error useNumber bool disallowUnknownFields bool - // safeUnquote is the number of current string literal bytes that don't - // need to be unquoted. When negative, no bytes need unquoting. - safeUnquote int } // readIndex returns the position of the last byte read. @@ -376,27 +373,13 @@ func (d *decodeState) rescanLiteral() { Switch: switch data[i-1] { case '"': // string - // safeUnquote is initialized at -1, which means that all bytes - // checked so far can be unquoted at a later time with no work - // at all. When reaching the closing '"', if safeUnquote is - // still -1, all bytes can be unquoted with no work. Otherwise, - // only those bytes up until the first '\\' or non-ascii rune - // can be safely unquoted. - safeUnquote := -1 for ; i < len(data); i++ { - if c := data[i]; c == '\\' { - if safeUnquote < 0 { // first unsafe byte - safeUnquote = int(i - d.off) - } + switch data[i] { + case '\\': i++ // escaped char - } else if c == '"' { - d.safeUnquote = safeUnquote + case '"': i++ // tokenize the closing quote too break Switch - } else if c >= utf8.RuneSelf { - if safeUnquote < 0 { // first unsafe byte - safeUnquote = int(i - d.off) - } } } case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number @@ -749,7 +732,7 @@ func (d *decodeState) object(v reflect.Value) error { start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] - key, ok := d.unquoteBytes(item) + key, ok := unquoteBytes(item) if !ok { panic(phasePanicMsg) } @@ -950,7 +933,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())}) return nil } - s, ok := d.unquoteBytes(item) + s, ok := unquoteBytes(item) if !ok { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) @@ -1001,7 +984,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool } case '"': // string - s, ok := d.unquoteBytes(item) + s, ok := unquoteBytes(item) if !ok { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) @@ -1159,7 +1142,7 @@ func (d *decodeState) objectInterface() map[string]interface{} { start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] - key, ok := d.unquote(item) + key, ok := unquote(item) if !ok { panic(phasePanicMsg) } @@ -1208,7 +1191,7 @@ func (d *decodeState) literalInterface() interface{} { return c == 't' case '"': // string - s, ok := d.unquote(item) + s, ok := unquote(item) if !ok { panic(phasePanicMsg) } @@ -1251,21 +1234,38 @@ func getu4(s []byte) rune { // unquote converts a quoted JSON string literal s into an actual string t. // The rules are different than for Go, so cannot use strconv.Unquote. -func (d *decodeState) unquote(s []byte) (t string, ok bool) { - s, ok = d.unquoteBytes(s) +func unquote(s []byte) (t string, ok bool) { + s, ok = unquoteBytes(s) t = string(s) return } -func (d *decodeState) unquoteBytes(s []byte) (t []byte, ok bool) { - r := d.safeUnquote - // The bytes have been scanned, so we know that the first and last bytes - // are double quotes. +func unquoteBytes(s []byte) (t []byte, ok bool) { + if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { + return + } s = s[1 : len(s)-1] - // If there are no unusual characters, no unquoting is needed, so return - // a slice of the original bytes. - if r == -1 { + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { return s, true } diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 719a9fa290c..3f25893b419 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -1250,6 +1250,8 @@ var wrongStringTests = []wrongStringTest{ {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`}, {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`}, {`{"result":123}`, `json: invalid use of ,string struct tag, trying to unmarshal unquoted value into string`}, + {`{"result":"\""}`, `json: invalid use of ,string struct tag, trying to unmarshal "\"" into string`}, + {`{"result":"\"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "\"foo" into string`}, } // If people misuse the ,string modifier, the error message should be diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index 464ee3ece4f..67412763d64 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -137,7 +137,7 @@ import ( // string, an integer type, or implement encoding.TextMarshaler. The map keys // are sorted and used as JSON object keys by applying the following rules, // subject to the UTF-8 coercion described for string values above: -// - string keys are used directly +// - keys of any string type are used directly // - encoding.TextMarshalers are marshaled // - integer keys are converted to strings // @@ -460,7 +460,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { } } -func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) { +func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { va := v.Addr() if va.IsNil() { e.WriteString("null") @@ -470,7 +470,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) { b, err := m.MarshalJSON() if err == nil { // copy JSON into buffer, checking validity. - err = compact(&e.Buffer, b, true) + err = compact(&e.Buffer, b, opts.escapeHTML) } if err != nil { e.error(&MarshalerError{v.Type(), err}) diff --git a/libgo/go/encoding/json/fuzz.go b/libgo/go/encoding/json/fuzz.go index 4872b6f7ee1..be03f0d7ffc 100644 --- a/libgo/go/encoding/json/fuzz.go +++ b/libgo/go/encoding/json/fuzz.go @@ -33,7 +33,7 @@ func Fuzz(data []byte) (score int) { err = Unmarshal(m, u) if err != nil { fmt.Printf("v=%#v\n", v) - fmt.Println("m=%s\n", string(m)) + fmt.Printf("m=%s\n", m) panic(err) } } diff --git a/libgo/go/encoding/json/indent.go b/libgo/go/encoding/json/indent.go index 1b49a369e33..fba19548c92 100644 --- a/libgo/go/encoding/json/indent.go +++ b/libgo/go/encoding/json/indent.go @@ -8,9 +8,6 @@ import "bytes" // Compact appends to dst the JSON-encoded src with // insignificant space characters elided. -// Like Marshal, Compact applies HTMLEscape to any -// string literals so that the JSON will be safe to embed -// inside HTML