mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
[dev.typeparams] all: merge master (296ddf2
) into dev.typeparams
Conflicts: - src/runtime/runtime2.go On master, CL 317191 fixed the mentions of gc/reflect.go in comments to reflectdata/reflect.go; but on dev.typeparams, CL 325921 fixed that the same comment to reflect that deferstruct actually ended up in ssagen/ssa.go. Merge List: + 2021-07-08296ddf2a93
net: filter bad names from Lookup functions instead of hard failing + 2021-07-08ce76298ee7
Update oudated comment + 2021-07-082ca44fe221
doc/go1.17: linkify time.UnixMilli and time.UnixMicro + 2021-07-075c59e11f5e
cmd/compile: remove special-casing of blank in types.sconv{,2} + 2021-07-07b003a8b1ae
cmd/compile: optimize types.sconv + 2021-07-0711f5df2d67
cmd/compile: extract pkgqual from symfmt + 2021-07-07991fd381d5
cmd/go: don't lock .mod and .sum files for read in overlay + 2021-07-07186a3bb4b0
cmd/go/internal/modfetch/codehost: skip hg tests if no hg binary is present + 2021-07-0700c00558e1
cmd/go/internal/modload: remove unused functions + 2021-07-07f264879f74
cmd/go/internal/modload: fix an apparent typo in the AutoRoot comment + 2021-07-07c96833e5ba
doc: remove stale comment about arm64 port Change-Id: I849046b6d8f7421f60323549f3f763ef418bf9e7
This commit is contained in:
commit
2b1d70a137
|
@ -827,10 +827,6 @@ The other codes are <code>-></code> (arithmetic right shift),
|
|||
|
||||
<h3 id="arm64">ARM64</h3>
|
||||
|
||||
<p>
|
||||
The ARM64 port is in an experimental state.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>R18</code> is the "platform register", reserved on the Apple platform.
|
||||
To prevent accidental misuse, the register is named <code>R18_PLATFORM</code>.
|
||||
|
|
|
@ -1132,10 +1132,13 @@ func Foo() bool {
|
|||
|
||||
<p><!-- CL 293349 -->
|
||||
The new <a href="/pkg/time/#Time.UnixMilli"><code>Time.UnixMilli</code></a> and
|
||||
<a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a> methods return the number of milliseconds and
|
||||
microseconds elapsed since January 1, 1970 UTC respectively.<br>
|
||||
The new <code>UnixMilli</code> and <code>UnixMicro</code> functions return local Time corresponding to given
|
||||
Unix time.
|
||||
<a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a>
|
||||
methods return the number of milliseconds and microseconds elapsed since
|
||||
January 1, 1970 UTC respectively.
|
||||
<br />
|
||||
The new <a href="/pkg/time/#UnixMilli"><code>UnixMilli</code></a> and
|
||||
<a href="/pkg/time/#UnixMicro"><code>UnixMicro</code></a> functions
|
||||
return the local <code>Time</code> corresponding to the given Unix time.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 300996 -->
|
||||
|
|
|
@ -651,7 +651,7 @@ var kinds = []int{
|
|||
// tflag is documented in reflect/type.go.
|
||||
//
|
||||
// tflag values must be kept in sync with copies in:
|
||||
// cmd/compile/internal/gc/reflect.go
|
||||
// cmd/compile/internal/reflectdata/reflect.go
|
||||
// cmd/link/internal/ld/decodesym.go
|
||||
// reflect/type.go
|
||||
// runtime/type.go
|
||||
|
|
|
@ -109,14 +109,18 @@ func sconv(s *Sym, verb rune, mode fmtMode) string {
|
|||
return "<S>"
|
||||
}
|
||||
|
||||
if s.Name == "_" {
|
||||
return "_"
|
||||
q := pkgqual(s.Pkg, verb, mode)
|
||||
if q == "" {
|
||||
return s.Name
|
||||
}
|
||||
|
||||
buf := fmtBufferPool.Get().(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
defer fmtBufferPool.Put(buf)
|
||||
|
||||
symfmt(buf, s, verb, mode)
|
||||
buf.WriteString(q)
|
||||
buf.WriteByte('.')
|
||||
buf.WriteString(s.Name)
|
||||
return InternString(buf.Bytes())
|
||||
}
|
||||
|
||||
|
@ -128,56 +132,49 @@ func sconv2(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
|
|||
b.WriteString("<S>")
|
||||
return
|
||||
}
|
||||
if s.Name == "_" {
|
||||
b.WriteString("_")
|
||||
return
|
||||
}
|
||||
|
||||
symfmt(b, s, verb, mode)
|
||||
}
|
||||
|
||||
func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
|
||||
if q := pkgqual(s.Pkg, verb, mode); q != "" {
|
||||
b.WriteString(q)
|
||||
b.WriteByte('.')
|
||||
}
|
||||
b.WriteString(s.Name)
|
||||
}
|
||||
|
||||
// pkgqual returns the qualifier that should be used for printing
|
||||
// symbols from the given package in the given mode.
|
||||
// If it returns the empty string, no qualification is needed.
|
||||
func pkgqual(pkg *Pkg, verb rune, mode fmtMode) string {
|
||||
if verb != 'S' {
|
||||
switch mode {
|
||||
case fmtGo: // This is for the user
|
||||
if s.Pkg == BuiltinPkg || s.Pkg == LocalPkg {
|
||||
b.WriteString(s.Name)
|
||||
return
|
||||
if pkg == BuiltinPkg || pkg == LocalPkg {
|
||||
return ""
|
||||
}
|
||||
|
||||
// If the name was used by multiple packages, display the full path,
|
||||
if s.Pkg.Name != "" && NumImport[s.Pkg.Name] > 1 {
|
||||
fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name)
|
||||
return
|
||||
if pkg.Name != "" && NumImport[pkg.Name] > 1 {
|
||||
return strconv.Quote(pkg.Path)
|
||||
}
|
||||
b.WriteString(s.Pkg.Name)
|
||||
b.WriteByte('.')
|
||||
b.WriteString(s.Name)
|
||||
return
|
||||
return pkg.Name
|
||||
|
||||
case fmtDebug:
|
||||
b.WriteString(s.Pkg.Name)
|
||||
b.WriteByte('.')
|
||||
b.WriteString(s.Name)
|
||||
return
|
||||
return pkg.Name
|
||||
|
||||
case fmtTypeIDName:
|
||||
// dcommontype, typehash
|
||||
b.WriteString(s.Pkg.Name)
|
||||
b.WriteByte('.')
|
||||
b.WriteString(s.Name)
|
||||
return
|
||||
return pkg.Name
|
||||
|
||||
case fmtTypeID:
|
||||
// (methodsym), typesym, weaksym
|
||||
b.WriteString(s.Pkg.Prefix)
|
||||
b.WriteByte('.')
|
||||
b.WriteString(s.Name)
|
||||
return
|
||||
return pkg.Prefix
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteString(s.Name)
|
||||
return ""
|
||||
}
|
||||
|
||||
// Type
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"io/fs"
|
||||
"os"
|
||||
|
||||
"cmd/go/internal/fsys"
|
||||
"cmd/go/internal/lockedfile/internal/filelock"
|
||||
)
|
||||
|
||||
|
@ -21,7 +20,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
|
|||
// calls for Linux and Windows anyway, so it's simpler to use that approach
|
||||
// consistently.
|
||||
|
||||
f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
|
||||
f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cmd/go/internal/fsys"
|
||||
)
|
||||
|
||||
// Opening an exclusive-use file returns an error.
|
||||
|
@ -59,7 +57,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
|
|||
// If the file was unpacked or created by some other program, it might not
|
||||
// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
|
||||
// can be confident that a successful OpenFile implies exclusive use.
|
||||
if fi, err := fsys.Stat(name); err == nil {
|
||||
if fi, err := os.Stat(name); err == nil {
|
||||
if fi.Mode()&fs.ModeExclusive == 0 {
|
||||
if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
|
||||
return nil, err
|
||||
|
@ -72,7 +70,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
|
|||
nextSleep := 1 * time.Millisecond
|
||||
const maxSleep = 500 * time.Millisecond
|
||||
for {
|
||||
f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
|
||||
f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
|
||||
if err == nil {
|
||||
return f, nil
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"archive/zip"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/fs"
|
||||
|
@ -47,12 +46,6 @@ var altRepos = []string{
|
|||
var localGitRepo string
|
||||
|
||||
func testMain(m *testing.M) int {
|
||||
if _, err := exec.LookPath("git"); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "skipping because git binary not found")
|
||||
fmt.Println("PASS")
|
||||
return 0
|
||||
}
|
||||
|
||||
dir, err := os.MkdirTemp("", "gitrepo-test-")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -60,6 +53,7 @@ func testMain(m *testing.M) int {
|
|||
defer os.RemoveAll(dir)
|
||||
|
||||
if testenv.HasExternalNetwork() && testenv.HasExec() {
|
||||
if _, err := exec.LookPath("git"); err == nil {
|
||||
// Clone gitrepo1 into a local directory.
|
||||
// If we use a file:// URL to access the local directory,
|
||||
// then git starts up all the usual protocol machinery,
|
||||
|
@ -72,11 +66,12 @@ func testMain(m *testing.M) int {
|
|||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func testRepo(remote string) (Repo, error) {
|
||||
func testRepo(t *testing.T, remote string) (Repo, error) {
|
||||
if remote == "localGitRepo" {
|
||||
// Convert absolute path to file URL. LocalGitRepo will not accept
|
||||
// Windows absolute paths because they look like a host:path remote.
|
||||
|
@ -87,15 +82,17 @@ func testRepo(remote string) (Repo, error) {
|
|||
} else {
|
||||
url = "file:///" + filepath.ToSlash(localGitRepo)
|
||||
}
|
||||
testenv.MustHaveExecPath(t, "git")
|
||||
return LocalGitRepo(url)
|
||||
}
|
||||
kind := "git"
|
||||
vcs := "git"
|
||||
for _, k := range []string{"hg"} {
|
||||
if strings.Contains(remote, "/"+k+"/") {
|
||||
kind = k
|
||||
vcs = k
|
||||
}
|
||||
}
|
||||
return NewRepo(kind, remote)
|
||||
testenv.MustHaveExecPath(t, vcs)
|
||||
return NewRepo(vcs, remote)
|
||||
}
|
||||
|
||||
var tagsTests = []struct {
|
||||
|
@ -116,7 +113,7 @@ func TestTags(t *testing.T) {
|
|||
|
||||
for _, tt := range tagsTests {
|
||||
f := func(t *testing.T) {
|
||||
r, err := testRepo(tt.repo)
|
||||
r, err := testRepo(t, tt.repo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -168,7 +165,7 @@ func TestLatest(t *testing.T) {
|
|||
|
||||
for _, tt := range latestTests {
|
||||
f := func(t *testing.T) {
|
||||
r, err := testRepo(tt.repo)
|
||||
r, err := testRepo(t, tt.repo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -221,7 +218,7 @@ func TestReadFile(t *testing.T) {
|
|||
|
||||
for _, tt := range readFileTests {
|
||||
f := func(t *testing.T) {
|
||||
r, err := testRepo(tt.repo)
|
||||
r, err := testRepo(t, tt.repo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -412,7 +409,7 @@ func TestReadZip(t *testing.T) {
|
|||
|
||||
for _, tt := range readZipTests {
|
||||
f := func(t *testing.T) {
|
||||
r, err := testRepo(tt.repo)
|
||||
r, err := testRepo(t, tt.repo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -581,7 +578,7 @@ func TestStat(t *testing.T) {
|
|||
|
||||
for _, tt := range statTests {
|
||||
f := func(t *testing.T) {
|
||||
r, err := testRepo(tt.repo)
|
||||
r, err := testRepo(t, tt.repo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/fsys"
|
||||
"cmd/go/internal/lockedfile"
|
||||
"cmd/go/internal/par"
|
||||
"cmd/go/internal/robustio"
|
||||
|
@ -416,7 +417,18 @@ func initGoSum() (bool, error) {
|
|||
|
||||
goSum.m = make(map[module.Version][]string)
|
||||
goSum.status = make(map[modSum]modSumStatus)
|
||||
data, err := lockedfile.Read(GoSumFile)
|
||||
var (
|
||||
data []byte
|
||||
err error
|
||||
)
|
||||
if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
|
||||
// Don't lock go.sum if it's part of the overlay.
|
||||
// On Plan 9, locking requires chmod, and we don't want to modify any file
|
||||
// in the overlay. See #44700.
|
||||
data, err = os.ReadFile(actualSumFile)
|
||||
} else {
|
||||
data, err = lockedfile.Read(GoSumFile)
|
||||
}
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return false, err
|
||||
}
|
||||
|
@ -716,6 +728,9 @@ Outer:
|
|||
if cfg.BuildMod == "readonly" {
|
||||
base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly")
|
||||
}
|
||||
if _, ok := fsys.OverlayPath(GoSumFile); ok {
|
||||
base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
|
||||
}
|
||||
|
||||
// Make a best-effort attempt to acquire the side lock, only to exclude
|
||||
// previous versions of the 'go' command from making simultaneous edits.
|
||||
|
|
|
@ -71,7 +71,7 @@ type Root int
|
|||
const (
|
||||
// AutoRoot is the default for most commands. modload.Init will look for
|
||||
// a go.mod file in the current directory or any parent. If none is found,
|
||||
// modules may be disabled (GO111MODULE=on) or commands may run in a
|
||||
// modules may be disabled (GO111MODULE=auto) or commands may run in a
|
||||
// limited module mode.
|
||||
AutoRoot Root = iota
|
||||
|
||||
|
@ -412,7 +412,16 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
|
|||
}
|
||||
|
||||
gomod := ModFilePath()
|
||||
data, err := lockedfile.Read(gomod)
|
||||
var data []byte
|
||||
var err error
|
||||
if gomodActual, ok := fsys.OverlayPath(gomod); ok {
|
||||
// Don't lock go.mod if it's part of the overlay.
|
||||
// On Plan 9, locking requires chmod, and we don't want to modify any file
|
||||
// in the overlay. See #44700.
|
||||
data, err = os.ReadFile(gomodActual)
|
||||
} else {
|
||||
data, err = lockedfile.Read(gomodActual)
|
||||
}
|
||||
if err != nil {
|
||||
base.Fatalf("go: %v", err)
|
||||
}
|
||||
|
@ -1026,6 +1035,13 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements)
|
|||
}
|
||||
return
|
||||
}
|
||||
gomod := ModFilePath()
|
||||
if _, ok := fsys.OverlayPath(gomod); ok {
|
||||
if dirty {
|
||||
base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
new, err := modFile.Format()
|
||||
if err != nil {
|
||||
|
|
|
@ -675,20 +675,6 @@ func DirImportPath(ctx context.Context, dir string) string {
|
|||
return "."
|
||||
}
|
||||
|
||||
// TargetPackages returns the list of packages in the target (top-level) module
|
||||
// matching pattern, which may be relative to the working directory, under all
|
||||
// build tag settings.
|
||||
func TargetPackages(ctx context.Context, pattern string) *search.Match {
|
||||
// TargetPackages is relative to the main module, so ensure that the main
|
||||
// module is a thing that can contain packages.
|
||||
LoadModFile(ctx) // Sets Target.
|
||||
ModRoot() // Emits an error if Target cannot contain packages.
|
||||
|
||||
m := search.NewMatch(pattern)
|
||||
matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{Target})
|
||||
return m
|
||||
}
|
||||
|
||||
// ImportMap returns the actual package import path
|
||||
// for an import path found in source code.
|
||||
// If the given import path does not appear in the source code
|
||||
|
@ -720,29 +706,6 @@ func PackageModule(path string) module.Version {
|
|||
return pkg.mod
|
||||
}
|
||||
|
||||
// PackageImports returns the imports for the package named by the import path.
|
||||
// Test imports will be returned as well if tests were loaded for the package
|
||||
// (i.e., if "all" was loaded or if LoadTests was set and the path was matched
|
||||
// by a command line argument). PackageImports will return nil for
|
||||
// unknown package paths.
|
||||
func PackageImports(path string) (imports, testImports []string) {
|
||||
pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
imports = make([]string, len(pkg.imports))
|
||||
for i, p := range pkg.imports {
|
||||
imports[i] = p.path
|
||||
}
|
||||
if pkg.test != nil {
|
||||
testImports = make([]string, len(pkg.test.imports))
|
||||
for i, p := range pkg.test.imports {
|
||||
testImports[i] = p.path
|
||||
}
|
||||
}
|
||||
return imports, testImports
|
||||
}
|
||||
|
||||
// Lookup returns the source directory, import path, and any loading error for
|
||||
// the package at path as imported from the package in parentDir.
|
||||
// Lookup requires that one of the Load functions in this package has already
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/fsys"
|
||||
"cmd/go/internal/lockedfile"
|
||||
"cmd/go/internal/modfetch"
|
||||
"cmd/go/internal/par"
|
||||
|
@ -601,8 +603,16 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
|
|||
dir = filepath.Join(ModRoot(), dir)
|
||||
}
|
||||
gomod := filepath.Join(dir, "go.mod")
|
||||
|
||||
data, err := lockedfile.Read(gomod)
|
||||
var data []byte
|
||||
var err error
|
||||
if gomodActual, ok := fsys.OverlayPath(gomod); ok {
|
||||
// Don't lock go.mod if it's part of the overlay.
|
||||
// On Plan 9, locking requires chmod, and we don't want to modify any file
|
||||
// in the overlay. See #44700.
|
||||
data, err = os.ReadFile(gomodActual)
|
||||
} else {
|
||||
data, err = lockedfile.Read(gomodActual)
|
||||
}
|
||||
if err != nil {
|
||||
return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
|
||||
}
|
||||
|
|
|
@ -920,8 +920,8 @@ func (e *PackageNotInModuleError) ImportPath() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// ModuleHasRootPackage returns whether module m contains a package m.Path.
|
||||
func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
|
||||
// moduleHasRootPackage returns whether module m contains a package m.Path.
|
||||
func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
|
||||
needSum := false
|
||||
root, isLocal, err := fetch(ctx, m, needSum)
|
||||
if err != nil {
|
||||
|
|
10
src/cmd/go/testdata/script/mod_overlay.txt
vendored
10
src/cmd/go/testdata/script/mod_overlay.txt
vendored
|
@ -21,7 +21,7 @@ go list -deps -overlay overlay.json .
|
|||
cd $WORK/gopath/src/get-doesnt-add-dep
|
||||
cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
|
||||
! go get -d -overlay overlay.json .
|
||||
stderr 'overlaid files can''t be opened for write'
|
||||
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
|
||||
cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
|
||||
|
||||
# Content of overlaid go.sum is used.
|
||||
|
@ -41,10 +41,10 @@ go mod verify -overlay overlay.json
|
|||
# attempting to update the file
|
||||
cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
|
||||
! go get -d -overlay overlay.json .
|
||||
stderr 'overlaid files can''t be opened for write'
|
||||
stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
|
||||
cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
|
||||
! go mod tidy -overlay overlay.json
|
||||
stderr 'overlaid files can''t be opened for write'
|
||||
stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
|
||||
cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
|
||||
|
||||
# -overlay works with -modfile.
|
||||
|
@ -56,7 +56,7 @@ go list -modfile=alternate.mod -overlay overlay.json .
|
|||
stdout 'found.the/module'
|
||||
# Even with -modfile, overlaid files can't be opened for write.
|
||||
! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote
|
||||
stderr 'overlaid files can''t be opened for write'
|
||||
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
|
||||
|
||||
# Carving out a module by adding an overlaid go.mod file
|
||||
cd $WORK/gopath/src/carve
|
||||
|
@ -78,7 +78,7 @@ go list -overlay overlay.json all
|
|||
stdout ^carve2/nomod$
|
||||
# Editing go.mod file fails because overlay is read only
|
||||
! go get -overlay overlay.json -d rsc.io/quote
|
||||
stderr 'overlaid files can''t be opened for write'
|
||||
stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
|
||||
! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod
|
||||
# Editing go.mod file succeeds because we use -modfile to redirect to same file
|
||||
go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote
|
||||
|
|
|
@ -16,12 +16,12 @@ import (
|
|||
|
||||
// Decoding the type.* symbols. This has to be in sync with
|
||||
// ../../runtime/type.go, or more specifically, with what
|
||||
// cmd/compile/internal/gc/reflect.go stuffs in these.
|
||||
// cmd/compile/internal/reflectdata/reflect.go stuffs in these.
|
||||
|
||||
// tflag is documented in reflect/type.go.
|
||||
//
|
||||
// tflag values must be kept in sync with copies in:
|
||||
// cmd/compile/internal/gc/reflect.go
|
||||
// cmd/compile/internal/reflectdata/reflect.go
|
||||
// cmd/link/internal/ld/decodesym.go
|
||||
// reflect/type.go
|
||||
// runtime/type.go
|
||||
|
|
|
@ -68,7 +68,7 @@ type Type interface {
|
|||
}
|
||||
|
||||
/*
|
||||
* These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
|
||||
* These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
|
||||
* A few are known to ../runtime/type.go to convey to debuggers.
|
||||
* They are also known to ../runtime/type.go.
|
||||
*/
|
||||
|
@ -111,7 +111,7 @@ const (
|
|||
// available in the memory directly following the rtype value.
|
||||
//
|
||||
// tflag values must be kept in sync with copies in:
|
||||
// cmd/compile/internal/gc/reflect.go
|
||||
// cmd/compile/internal/reflectdata/reflect.go
|
||||
// cmd/link/internal/ld/decodesym.go
|
||||
// runtime/type.go
|
||||
type tflag uint8
|
||||
|
|
|
@ -1846,6 +1846,17 @@ func TestCVE202133195(t *testing.T) {
|
|||
Target: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: n,
|
||||
Type: dnsmessage.TypeSRV,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.SRVResource{
|
||||
Target: dnsmessage.MustNewName("good.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypeMX:
|
||||
r.Answers = append(r.Answers,
|
||||
|
@ -1860,6 +1871,17 @@ func TestCVE202133195(t *testing.T) {
|
|||
MX: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("good.golang.org."),
|
||||
Type: dnsmessage.TypeMX,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.MXResource{
|
||||
MX: dnsmessage.MustNewName("good.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypeNS:
|
||||
r.Answers = append(r.Answers,
|
||||
|
@ -1874,6 +1896,17 @@ func TestCVE202133195(t *testing.T) {
|
|||
NS: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("good.golang.org."),
|
||||
Type: dnsmessage.TypeNS,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.NSResource{
|
||||
NS: dnsmessage.MustNewName("good.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypePTR:
|
||||
r.Answers = append(r.Answers,
|
||||
|
@ -1888,6 +1921,17 @@ func TestCVE202133195(t *testing.T) {
|
|||
PTR: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("good.golang.org."),
|
||||
Type: dnsmessage.TypePTR,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.PTRResource{
|
||||
PTR: dnsmessage.MustNewName("good.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
return r, nil
|
||||
|
@ -1903,25 +1947,53 @@ func TestCVE202133195(t *testing.T) {
|
|||
defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
|
||||
testHookHostsPath = "testdata/hosts"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
f func(*testing.T)
|
||||
}{
|
||||
{
|
||||
name: "CNAME",
|
||||
f: func(t *testing.T) {
|
||||
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
|
||||
_, err := r.LookupCNAME(context.Background(), "golang.org")
|
||||
if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err, expected)
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
_, err = LookupCNAME("golang.org")
|
||||
if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err, expected)
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
_, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
|
||||
if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SRV (bad record)",
|
||||
f: func(t *testing.T) {
|
||||
expected := []*SRV{
|
||||
{
|
||||
Target: "good.golang.org.",
|
||||
},
|
||||
}
|
||||
_, _, err = LookupSRV("target", "tcp", "golang.org")
|
||||
if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
|
||||
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
|
||||
_, records, err := r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
_, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.")
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
_, records, err = LookupSRV("target", "tcp", "golang.org")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SRV (bad header)",
|
||||
f: func(t *testing.T) {
|
||||
_, _, err := r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.")
|
||||
if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
|
||||
}
|
||||
|
@ -1929,33 +2001,85 @@ func TestCVE202133195(t *testing.T) {
|
|||
if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
|
||||
}
|
||||
|
||||
_, err = r.LookupMX(context.Background(), "golang.org")
|
||||
if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err, expected)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MX",
|
||||
f: func(t *testing.T) {
|
||||
expected := []*MX{
|
||||
{
|
||||
Host: "good.golang.org.",
|
||||
},
|
||||
}
|
||||
_, err = LookupMX("golang.org")
|
||||
if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupMX returned unexpected error, got %q, want %q", err, expected)
|
||||
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
|
||||
records, err := r.LookupMX(context.Background(), "golang.org")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
records, err = LookupMX("golang.org")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NS",
|
||||
f: func(t *testing.T) {
|
||||
expected := []*NS{
|
||||
{
|
||||
Host: "good.golang.org.",
|
||||
},
|
||||
}
|
||||
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
|
||||
records, err := r.LookupNS(context.Background(), "golang.org")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
records, err = LookupNS("golang.org")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Addr",
|
||||
f: func(t *testing.T) {
|
||||
expected := []string{"good.golang.org."}
|
||||
expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "192.0.2.42"}
|
||||
records, err := r.LookupAddr(context.Background(), "192.0.2.42")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
records, err = LookupAddr("192.0.2.42")
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(records, expected) {
|
||||
t.Error("Unexpected record set")
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = r.LookupNS(context.Background(), "golang.org")
|
||||
if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err, expected)
|
||||
}
|
||||
_, err = LookupNS("golang.org")
|
||||
if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupNS returned unexpected error, got %q, want %q", err, expected)
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, tc.f)
|
||||
}
|
||||
|
||||
_, err = r.LookupAddr(context.Background(), "192.0.2.42")
|
||||
if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err, expected)
|
||||
}
|
||||
_, err = LookupAddr("192.0.2.42")
|
||||
if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNullMX(t *testing.T) {
|
||||
|
|
|
@ -424,7 +424,7 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error)
|
|||
return "", err
|
||||
}
|
||||
if !isDomainName(cname) {
|
||||
return "", &DNSError{Err: "CNAME target is invalid", Name: host}
|
||||
return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host}
|
||||
}
|
||||
return cname, nil
|
||||
}
|
||||
|
@ -440,7 +440,9 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error)
|
|||
// and proto are empty strings, LookupSRV looks up name directly.
|
||||
//
|
||||
// The returned service names are validated to be properly
|
||||
// formatted presentation-format domain names.
|
||||
// formatted presentation-format domain names. If the response contains
|
||||
// invalid names, those records are filtered out and an error
|
||||
// will be returned alongside the the remaining results, if any.
|
||||
func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
|
||||
return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
|
||||
}
|
||||
|
@ -456,7 +458,9 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err err
|
|||
// and proto are empty strings, LookupSRV looks up name directly.
|
||||
//
|
||||
// The returned service names are validated to be properly
|
||||
// formatted presentation-format domain names.
|
||||
// formatted presentation-format domain names. If the response contains
|
||||
// invalid names, those records are filtered out and an error
|
||||
// will be returned alongside the the remaining results, if any.
|
||||
func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
|
||||
cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
|
||||
if err != nil {
|
||||
|
@ -465,21 +469,28 @@ func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (
|
|||
if cname != "" && !isDomainName(cname) {
|
||||
return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
|
||||
}
|
||||
filteredAddrs := make([]*SRV, 0, len(addrs))
|
||||
for _, addr := range addrs {
|
||||
if addr == nil {
|
||||
continue
|
||||
}
|
||||
if !isDomainName(addr.Target) {
|
||||
return "", nil, &DNSError{Err: "SRV target is invalid", Name: name}
|
||||
continue
|
||||
}
|
||||
filteredAddrs = append(filteredAddrs, addr)
|
||||
}
|
||||
return cname, addrs, nil
|
||||
if len(addrs) != len(filteredAddrs) {
|
||||
return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
|
||||
}
|
||||
return cname, filteredAddrs, nil
|
||||
}
|
||||
|
||||
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
|
||||
//
|
||||
// The returned mail server names are validated to be properly
|
||||
// formatted presentation-format domain names.
|
||||
// formatted presentation-format domain names. If the response contains
|
||||
// invalid names, those records are filtered out and an error
|
||||
// will be returned alongside the the remaining results, if any.
|
||||
//
|
||||
// LookupMX uses context.Background internally; to specify the context, use
|
||||
// Resolver.LookupMX.
|
||||
|
@ -490,12 +501,15 @@ func LookupMX(name string) ([]*MX, error) {
|
|||
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
|
||||
//
|
||||
// The returned mail server names are validated to be properly
|
||||
// formatted presentation-format domain names.
|
||||
// formatted presentation-format domain names. If the response contains
|
||||
// invalid names, those records are filtered out and an error
|
||||
// will be returned alongside the the remaining results, if any.
|
||||
func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
|
||||
records, err := r.lookupMX(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filteredMX := make([]*MX, 0, len(records))
|
||||
for _, mx := range records {
|
||||
if mx == nil {
|
||||
continue
|
||||
|
@ -503,16 +517,22 @@ func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
|
|||
// Bypass the hostname validity check for targets which contain only a dot,
|
||||
// as this is used to represent a 'Null' MX record.
|
||||
if mx.Host != "." && !isDomainName(mx.Host) {
|
||||
return nil, &DNSError{Err: "MX target is invalid", Name: name}
|
||||
continue
|
||||
}
|
||||
filteredMX = append(filteredMX, mx)
|
||||
}
|
||||
return records, nil
|
||||
if len(records) != len(filteredMX) {
|
||||
return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
|
||||
}
|
||||
return filteredMX, nil
|
||||
}
|
||||
|
||||
// LookupNS returns the DNS NS records for the given domain name.
|
||||
//
|
||||
// The returned name server names are validated to be properly
|
||||
// formatted presentation-format domain names.
|
||||
// formatted presentation-format domain names. If the response contains
|
||||
// invalid names, those records are filtered out and an error
|
||||
// will be returned alongside the the remaining results, if any.
|
||||
//
|
||||
// LookupNS uses context.Background internally; to specify the context, use
|
||||
// Resolver.LookupNS.
|
||||
|
@ -523,21 +543,28 @@ func LookupNS(name string) ([]*NS, error) {
|
|||
// LookupNS returns the DNS NS records for the given domain name.
|
||||
//
|
||||
// The returned name server names are validated to be properly
|
||||
// formatted presentation-format domain names.
|
||||
// formatted presentation-format domain names. If the response contains
|
||||
// invalid names, those records are filtered out and an error
|
||||
// will be returned alongside the the remaining results, if any.
|
||||
func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
|
||||
records, err := r.lookupNS(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filteredNS := make([]*NS, 0, len(records))
|
||||
for _, ns := range records {
|
||||
if ns == nil {
|
||||
continue
|
||||
}
|
||||
if !isDomainName(ns.Host) {
|
||||
return nil, &DNSError{Err: "NS target is invalid", Name: name}
|
||||
continue
|
||||
}
|
||||
filteredNS = append(filteredNS, ns)
|
||||
}
|
||||
return records, nil
|
||||
if len(records) != len(filteredNS) {
|
||||
return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
|
||||
}
|
||||
return filteredNS, nil
|
||||
}
|
||||
|
||||
// LookupTXT returns the DNS TXT records for the given domain name.
|
||||
|
@ -557,7 +584,8 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)
|
|||
// of names mapping to that address.
|
||||
//
|
||||
// The returned names are validated to be properly formatted presentation-format
|
||||
// domain names.
|
||||
// domain names. If the response contains invalid names, those records are filtered
|
||||
// out and an error will be returned alongside the the remaining results, if any.
|
||||
//
|
||||
// When using the host C library resolver, at most one result will be
|
||||
// returned. To bypass the host resolver, use a custom Resolver.
|
||||
|
@ -572,16 +600,26 @@ func LookupAddr(addr string) (names []string, err error) {
|
|||
// of names mapping to that address.
|
||||
//
|
||||
// The returned names are validated to be properly formatted presentation-format
|
||||
// domain names.
|
||||
// domain names. If the response contains invalid names, those records are filtered
|
||||
// out and an error will be returned alongside the the remaining results, if any.
|
||||
func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
|
||||
names, err := r.lookupAddr(ctx, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filteredNames := make([]string, 0, len(names))
|
||||
for _, name := range names {
|
||||
if !isDomainName(name) {
|
||||
return nil, &DNSError{Err: "PTR target is invalid", Name: addr}
|
||||
if isDomainName(name) {
|
||||
filteredNames = append(filteredNames, name)
|
||||
}
|
||||
}
|
||||
return names, nil
|
||||
if len(names) != len(filteredNames) {
|
||||
return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr}
|
||||
}
|
||||
return filteredNames, nil
|
||||
}
|
||||
|
||||
// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup...
|
||||
// method recieves DNS records which contain invalid DNS names. This may be returned alongside
|
||||
// results which have had the malformed records filtered out.
|
||||
var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names"
|
||||
|
|
|
@ -229,7 +229,7 @@ type Type interface {
|
|||
// See https://golang.org/issue/4876 for more details.
|
||||
|
||||
/*
|
||||
* These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
|
||||
* These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
|
||||
* A few are known to ../runtime/type.go to convey to debuggers.
|
||||
* They are also known to ../runtime/type.go.
|
||||
*/
|
||||
|
@ -272,7 +272,7 @@ const (
|
|||
// available in the memory directly following the rtype value.
|
||||
//
|
||||
// tflag values must be kept in sync with copies in:
|
||||
// cmd/compile/internal/gc/reflect.go
|
||||
// cmd/compile/internal/reflectdata/reflect.go
|
||||
// cmd/link/internal/ld/decodesym.go
|
||||
// runtime/type.go
|
||||
type tflag uint8
|
||||
|
@ -1911,7 +1911,7 @@ func MapOf(key, elem Type) Type {
|
|||
|
||||
// Make a map type.
|
||||
// Note: flag values must match those used in the TMAP case
|
||||
// in ../cmd/compile/internal/gc/reflect.go:writeType.
|
||||
// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
|
||||
var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
|
||||
mt := **(**mapType)(unsafe.Pointer(&imap))
|
||||
mt.str = resolveReflectName(newName(s, "", false))
|
||||
|
@ -2842,7 +2842,7 @@ func runtimeStructField(field StructField) (structField, string) {
|
|||
|
||||
// typeptrdata returns the length in bytes of the prefix of t
|
||||
// containing pointer data. Anything after this offset is scalar data.
|
||||
// keep in sync with ../cmd/compile/internal/gc/reflect.go
|
||||
// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
|
||||
func typeptrdata(t *rtype) uintptr {
|
||||
switch t.Kind() {
|
||||
case Struct:
|
||||
|
@ -2866,7 +2866,7 @@ func typeptrdata(t *rtype) uintptr {
|
|||
}
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/gc/reflect.go for derivation of constant.
|
||||
// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
|
||||
const maxPtrmaskBytes = 2048
|
||||
|
||||
// ArrayOf returns the array type with the given length and element type.
|
||||
|
|
|
@ -895,7 +895,7 @@ type funcinl struct {
|
|||
// layout of Itab known to compilers
|
||||
// allocated in non-garbage-collected memory
|
||||
// Needs to be in sync with
|
||||
// ../cmd/compile/internal/gc/reflect.go:/^func.WriteTabs.
|
||||
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
|
||||
type itab struct {
|
||||
inter *interfacetype
|
||||
_type *_type
|
||||
|
|
|
@ -16,7 +16,7 @@ const debugSelect = false
|
|||
|
||||
// Select case descriptor.
|
||||
// Known to compiler.
|
||||
// Changes here must also be made in src/cmd/internal/gc/select.go's scasetype.
|
||||
// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
|
||||
type scase struct {
|
||||
c *hchan // chan
|
||||
elem unsafe.Pointer // data element
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
// tflag is documented in reflect/type.go.
|
||||
//
|
||||
// tflag values must be kept in sync with copies in:
|
||||
// cmd/compile/internal/gc/reflect.go
|
||||
// cmd/compile/internal/reflectdata/reflect.go
|
||||
// cmd/link/internal/ld/decodesym.go
|
||||
// reflect/type.go
|
||||
// internal/reflectlite/type.go
|
||||
|
@ -28,7 +28,7 @@ const (
|
|||
)
|
||||
|
||||
// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
|
||||
// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and
|
||||
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
|
||||
// ../reflect/type.go:/^type.rtype.
|
||||
// ../internal/reflectlite/type.go:/^type.rtype.
|
||||
type _type struct {
|
||||
|
@ -386,7 +386,7 @@ type maptype struct {
|
|||
}
|
||||
|
||||
// Note: flag values must match those used in the TMAP case
|
||||
// in ../cmd/compile/internal/gc/reflect.go:writeType.
|
||||
// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
|
||||
func (mt *maptype) indirectkey() bool { // store ptr to key instead of key itself
|
||||
return mt.flags&1 != 0
|
||||
}
|
||||
|
|
9
test/fixedbugs/issue47087.dir/a.go
Normal file
9
test/fixedbugs/issue47087.dir/a.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2021 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 a
|
||||
|
||||
func F() interface{} { return struct{ _ []int }{} }
|
||||
|
||||
var X = F()
|
9
test/fixedbugs/issue47087.dir/b.go
Normal file
9
test/fixedbugs/issue47087.dir/b.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2021 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 b
|
||||
|
||||
func F() interface{} { return struct{ _ []int }{} }
|
||||
|
||||
var X = F()
|
19
test/fixedbugs/issue47087.dir/main.go
Normal file
19
test/fixedbugs/issue47087.dir/main.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2021 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 main
|
||||
|
||||
import (
|
||||
"a"
|
||||
"b"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if a.F() == b.F() {
|
||||
panic("FAIL")
|
||||
}
|
||||
if a.X == b.X {
|
||||
panic("FAIL")
|
||||
}
|
||||
}
|
7
test/fixedbugs/issue47087.go
Normal file
7
test/fixedbugs/issue47087.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
// rundir
|
||||
|
||||
// Copyright 2021 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 ignored
|
Loading…
Reference in a new issue