[dev.typeparams] all: merge master (16e82be) into dev.typeparams

Merge List:

+ 2021-06-21 16e82be454 runtime: fix crash during VDSO calls on PowerPC
+ 2021-06-21 2e542c3c06 runtime/pprof: deflake TestMorestack more
+ 2021-06-21 ced0fdbad0 doc/go1.17: note deprecation of 'go get' for installing commands
+ 2021-06-21 7a5e7047a4 doc/go1.17: add Go 1.18 pre-announcements
+ 2021-06-21 85a2e24afd doc/go1.17: add security-related release notes
+ 2021-06-21 1de332996c doc/go1.17: document go/parser.SkipObjectResolution
+ 2021-06-21 117ebe0f52 cmd/go: do not require the module cache to exist for 'go mod edit'
+ 2021-06-20 460900a7b5 os/signal: test with a significantly longer fatal timeout
+ 2021-06-19 b73cc4b02b database/sql: do not rely on timeout for deadlock test
+ 2021-06-18 86743e7d86 image: add RGBA64Image interface
+ 2021-06-18 9401172166 runtime: clarify Frames.Next documentation
+ 2021-06-18 57aaa19aae runtime: disable CPU profiling before removing the SIGPROF handler
+ 2021-06-18 6f22d2c682 doc/go1.17: fix typo
+ 2021-06-17 45f251ad6c cmd/pprof,runtime/pprof: disable test on more broken platforms
+ 2021-06-17 ed834853ad cmd/go: replace a TODO with an explanatory comment
+ 2021-06-17 4dede02550 cmd/pprof: make ObjAddr a no-op
+ 2021-06-17 97cee43c93 testing: drop unusual characters from TempDir directory name
+ 2021-06-17 b0355a3e72 time: fix receiver for Time.IsDST method
+ 2021-06-17 881b6ea7ba doc/go1.17: fix redundant space
+ 2021-06-16 0e67ce3d28 cmd/go: in lazy modules, add transitive imports for 'go get' arguments
+ 2021-06-16 6ea2af0890 cmd/go: add a regression test for #45979
+ 2021-06-16 a294e4e798 math/rand: mention half-open intervals explicitly
+ 2021-06-16 a6a853f94c cmd/asm: restore supporting of *1 scaling on ARM64

Change-Id: Ifdcb817fd44b4fa9c477042b41da55d1d769b016
This commit is contained in:
Cuong Manh Le 2021-06-22 00:35:07 +07:00
commit d626ba27bb
30 changed files with 967 additions and 96 deletions

View file

@ -28,6 +28,38 @@ pkg encoding/csv, method (*Reader) FieldPos(int) (int, int)
pkg go/build, type Context struct, ToolTags []string
pkg go/parser, const SkipObjectResolution = 64
pkg go/parser, const SkipObjectResolution Mode
pkg image, method (*Alpha) RGBA64At(int, int) color.RGBA64
pkg image, method (*Alpha) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*Alpha16) RGBA64At(int, int) color.RGBA64
pkg image, method (*Alpha16) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*CMYK) RGBA64At(int, int) color.RGBA64
pkg image, method (*CMYK) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*Gray) RGBA64At(int, int) color.RGBA64
pkg image, method (*Gray) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*Gray16) RGBA64At(int, int) color.RGBA64
pkg image, method (*Gray16) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*NRGBA) RGBA64At(int, int) color.RGBA64
pkg image, method (*NRGBA) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*NRGBA64) RGBA64At(int, int) color.RGBA64
pkg image, method (*NRGBA64) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*NYCbCrA) RGBA64At(int, int) color.RGBA64
pkg image, method (*Paletted) RGBA64At(int, int) color.RGBA64
pkg image, method (*Paletted) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*RGBA) RGBA64At(int, int) color.RGBA64
pkg image, method (*RGBA) SetRGBA64(int, int, color.RGBA64)
pkg image, method (*YCbCr) RGBA64At(int, int) color.RGBA64
pkg image, type RGBA64Image interface { At, Bounds, ColorModel, RGBA64At }
pkg image, type RGBA64Image interface, At(int, int) color.Color
pkg image, type RGBA64Image interface, Bounds() Rectangle
pkg image, type RGBA64Image interface, ColorModel() color.Model
pkg image, type RGBA64Image interface, RGBA64At(int, int) color.RGBA64
pkg image/draw, type RGBA64Image interface { At, Bounds, ColorModel, RGBA64At, Set, SetRGBA64 }
pkg image/draw, type RGBA64Image interface, At(int, int) color.Color
pkg image/draw, type RGBA64Image interface, Bounds() image.Rectangle
pkg image/draw, type RGBA64Image interface, ColorModel() color.Model
pkg image/draw, type RGBA64Image interface, RGBA64At(int, int) color.RGBA64
pkg image/draw, type RGBA64Image interface, Set(int, int, color.Color)
pkg image/draw, type RGBA64Image interface, SetRGBA64(int, int, color.RGBA64)
pkg io/fs, func FileInfoToDirEntry(FileInfo) DirEntry
pkg math, const MaxFloat64 = 1.79769e+308 // 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
pkg math, const MaxInt = 9223372036854775807
@ -153,7 +185,7 @@ pkg time, const Layout = "01/02 03:04:05PM '06 -0700"
pkg time, const Layout ideal-string
pkg time, func UnixMicro(int64) Time
pkg time, func UnixMilli(int64) Time
pkg time, method (*Time) IsDST() bool
pkg time, method (Time) GoString() string
pkg time, method (Time) IsDST() bool
pkg time, method (Time) UnixMicro() int64
pkg time, method (Time) UnixMilli() int64

View file

@ -162,7 +162,7 @@ Do not send CLs removing the interior tags from such phrases.
By default, <code>go</code> <code>mod</code> <code>tidy</code> verifies that
the selected versions of dependencies relevant to the main module are the same
versions that would be used by the prior Go release (Go 1.16 for a module that
spsecifies <code>go</code> <code>1.17</code>), and preserves
specifies <code>go</code> <code>1.17</code>), and preserves
the <code>go.sum</code> entries needed by that release even for dependencies
that are not normally needed by other commands.
</p>
@ -214,6 +214,16 @@ Do not send CLs removing the interior tags from such phrases.
<code>environment</code> for details.
</p>
<p><!-- golang.org/issue/43684 -->
<code>go</code> <code>get</code> prints a deprecation warning when installing
commands outside the main module (without the <code>-d</code> flag).
<code>go</code> <code>install</code> <code>cmd@version</code> should be used
instead to install a command at a specific version, using a suffix like
<code>@latest</code> or <code>@v1.2.3</code>. In Go 1.18, the <code>-d</code>
flag will always be enabled, and <code>go</code> <code>get</code> will only
be used to change dependencies in <code>go.mod</code>.
</p>
<h4 id="missing-go-directive"><code>go.mod</code> files missing <code>go</code> directives</h4>
<p><!-- golang.org/issue/44976 -->
@ -387,7 +397,7 @@ func Foo() bool {
registers instead of the stack. This work is enabled for Linux, MacOS, and
Windows on the 64-bit x86 architecture (the <code>linux/amd64</code>,
<code>darwin/amd64</code>, <code>windows/amd64</code> ports). For a
representative set of Go packages and programs, benchmarking has shown
representative set of Go packages and programs, benchmarking has shown
performance improvements of about 5%, and a typical reduction in binary size
of about 2%.
</p>
@ -441,6 +451,67 @@ func Foo() bool {
<a href="/pkg/runtime/cgo#Handle">runtime/cgo.Handle</a> for more information.
</p>
<h3 id="semicolons">URL query parsing</h3>
<!-- CL 325697, CL 326309 -->
<p>
The <code>net/url</code> and <code>net/http</code> packages used to accept
<code>";"</code> (semicolon) as a setting separator in URL queries, in
addition to <code>"&"</code> (ampersand). Now, settings with non-percent-encoded
semicolons are rejected and <code>net/http</code> servers will log a warning to
<a href="/pkg/net/http#Server.ErrorLog"><code>Server.ErrorLog</code></a>
when encountering one in a request URL.
</p>
<p>
For example, before Go 1.17 the <a href="/pkg/net/url#URL.Query"><code>Query</code></a>
method of the URL <code>example?a=1;b=2&c=3</code> would have returned
<code>map[a:[1] b:[2] c:[3]]</code>, while now it returns <code>map[c:[3]]</code>.
</p>
<p>
When encountering such a query string,
<a href="/pkg/net/url#URL.Query"><code>URL.Query</code></a>
and
<a href="/pkg/net/http#Request.FormValue"><code>Request.FormValue</code></a>
ignore any settings that contain a semicolon,
<a href="/pkg/net/url#ParseQuery"><code>ParseQuery</code></a>
returns the remaining settings and an error, and
<a href="/pkg/net/http#Request.ParseForm"><code>Request.ParseForm</code></a>
and
<a href="/pkg/net/http#Request.ParseMultipartForm"><code>Request.ParseMultipartForm</code></a>
return an error but still set <code>Request</code> fields based on the
remaining settings.
</p>
<p>
<code>net/http</code> users can restore the original behavior by using the new
<a href="/pkg/net/http#AllowQuerySemicolons"><code>AllowQuerySemicolons</code></a>
handler wrapper. This will also suppress the <code>ErrorLog</code> warning.
Note that accepting semicolons as query separators can lead to security issues
if different systems interpret cache keys differently.
See <a href="https://golang.org/issue/25192">issue 25192</a> for more information.
</p>
<h3 id="ALPN">TLS strict ALPN</h3>
<!-- CL 289209, CL 325432 -->
<p>
When <a href="/pkg/crypto/tls#Config.NextProtos"><code>Config.NextProtos</code></a>
is set, servers now enforce that there is an overlap between the configured
protocols and the ALPN protocols advertised by the client, if any. If there is
no mutually supported protocol, the connection is closed with the
<code>no_application_protocol</code> alert, as required by RFC 7301. This
helps mitigate <a href="https://alpaca-attack.com/">the ALPACA cross-protocol attack</a>.
</p>
<p>
As an exception, when the value <code>"h2"</code> is included in the server's
<code>Config.NextProtos</code>, HTTP/1.1 clients will be allowed to connect as
if they didn't support ALPN.
See <a href="https://golang.org/issue/46310">issue 46310</a> for more information.
</p>
<h3 id="minor_library_changes">Minor changes to the library</h3>
<p>
@ -549,14 +620,6 @@ func Foo() bool {
methods. Canceling the context after the handshake has finished has no effect.
</p>
<p><!-- CL 289209 -->
When <a href="/pkg/crypto/tls#Config.NextProtos"><code>Config.NextProtos</code></a>
is set, servers now enforce that there is an overlap between the
configured protocols and the protocols advertised by the client, if any.
If there is no overlap the connection is closed with the
<code>no_application_protocol</code> alert, as required by RFC 7301.
</p>
<p><!-- CL 314609 -->
Cipher suite ordering is now handled entirely by the
<code>crypto/tls</code> package. Currently, cipher suites are sorted based
@ -576,6 +639,15 @@ func Foo() bool {
weakness</a>. They are still enabled by default but only as a last resort,
thanks to the cipher suite ordering change above.
</p>
<p><!-- golang.org/issue/45428 -->
Beginning in the next release, Go 1.18, the
<a href="/pkg/crypto/tls/#Config.MinVersion"><code>Config.MinVersion</code></a>
for <code>crypto/tls</code> clients will default to TLS 1.2, disabling TLS 1.0
and TLS 1.1 by default. Applications will be able to override the change by
explicitly setting <code>Config.MinVersion</code>.
This will not affect <code>crypto/tls</code> servers.
</p>
</dd>
</dl><!-- crypto/tls -->
@ -603,6 +675,14 @@ func Foo() bool {
roots. This adds support for the new system trusted certificate store in
FreeBSD 12.2+.
</p>
<p><!-- golang.org/issue/41682 -->
Beginning in the next release, Go 1.18, <code>crypto/x509</code> will
reject certificates signed with the SHA-1 hash function. This doesn't
apply to self-signed root certificates. Practical attacks against SHA-1
<a href="https://shattered.io/">have been demonstrated in 2017</a> and publicly
trusted Certificate Authorities have not issued SHA-1 certificates since 2015.
</p>
</dd>
</dl><!-- crypto/x509 -->
@ -658,6 +738,22 @@ func Foo() bool {
</dd>
</dl><!-- encoding/csv -->
<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
<dd>
<p><!-- CL 277893 -->
When a comment appears within a
<a href="/pkg/encoding/xml/#Directive"><code>Directive</code></a>, it is now replaced
with a single space instead of being completely elided.
</p>
<p>
Invalid element or attribute names with leading, trailing, or multiple
colons are now stored unmodified into the
<a href="/pkg/encoding/xml/#Name"><code>Name.Local</code></a> field.
</p>
</dd>
</dl><!-- encoding/xml -->
<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
<dd>
<p><!-- CL 271788 -->
@ -693,6 +789,29 @@ func Foo() bool {
</dd>
</dl><!-- go/format -->
<dl id="go/parser"><dt><a href="/pkg/go/parser/">go/parser</a></dt>
<dd>
<p><!-- CL 306149 -->
The new <a href="/pkg/go/parser/#SkipObjectResolution"><code>SkipObjectResolution</code></a>
<code>Mode</code> value instructs the parser not to resolve identifiers to
their declaration. This may improve parsing speed.
</p>
</dd>
</dl><!-- go/parser -->
<dl id="image"><dt><a href="/pkg/image/">image</a></dt>
<dd>
<p><!-- CL 311129 -->
The concrete image types (<code>RGBA</code>, <code>Gray16</code> and so on)
now implement a new <a href="/pkg/image/#RGBA64Image"><code>RGBA64Image</code></a>
interface. Those concrete types, other than the chroma-subsampling
related <code>YCbCr</code> and <code>NYCbCrA</code>, also now implement
<a href="/pkg/image/draw/#RGBA64Image"><code>draw.RGBA64Image</code></a>, a
new interface in the <code>image/draw</code> package.
</p>
</dd>
</dl><!-- image -->
<dl id="io/fs"><dt><a href="/pkg/io/fs/">io/fs</a></dt>
<dd>
<p><!-- CL 293649 -->
@ -721,6 +840,20 @@ func Foo() bool {
</dd>
</dl><!-- mime -->
<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
<dd>
<p><!-- CL 313809 -->
<a href="/pkg/mime/multipart/#Part.FileName"><code>Part.FileName</code></a>
now applies
<a href="/pkg/path/filepath/#Base"><code>filepath.Base</code></a> to the
return value. This mitigates potential path traversal vulnerabilities in
applications that accept multipart messages, such as <code>net/http</code>
servers that call
<a href="/pkg/net/http/#Request.FormFile"><code>Request.FormFile</code></a>.
</p>
</dd>
</dl><!-- mime/multipart -->
<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
<dd>
<p><!-- CL 272668 -->
@ -740,7 +873,7 @@ func Foo() bool {
the <a href="/pkg/net/#Error"><code>net.Error</code></a> interface.
</p>
<p><!-- CL325829 -->
<p><!-- CL 325829 -->
The <a href="/pkg/net/#ParseIP"><code>ParseIP</code></a> and <a href="/pkg/net/#ParseCIDR"><code>ParseCIDR</code></a>
functions now reject IPv4 addresses which contain decimal components with leading zeros.
@ -771,6 +904,29 @@ func Foo() bool {
The <a href="/pkg/net/http/#ReadRequest"><code>ReadRequest</code></a> function
now returns an error when the request has multiple Host headers.
</p>
<p><!-- CL 313950 -->
When producing a redirect to the cleaned version of a URL,
<a href="/pkg/net/http/#ServeMux"><code>ServeMux</code></a> now always
uses relative URLs in the <code>Location</code> header. Previously it
would echo the full URL of the request, which could lead to unintended
redirects if the client could be made to send an absolute request URL.
</p>
<p><!-- CL 308009, CL 313489 -->
When interpreting certain HTTP headers handled by <code>net/http</code>,
non-ASCII characters are now ignored or rejected.
</p>
<p><!-- CL 325697 -->
If
<a href="/pkg/net/http/#Request.ParseForm"><code>Request.ParseForm</code></a>
returns an error when called by
<a href="/pkg/net/http/#Request.ParseMultipartForm"><code>Request.ParseMultipartForm</code></a>,
the latter now continues populating
<a href="/pkg/net/http/#Request.MultipartForm"><code>Request.MultipartForm</code></a>
before returning it.
</p>
</dd>
</dl><!-- net/http -->

View file

@ -1003,7 +1003,8 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
p.errorf("unimplemented two-register form")
}
a.Index = r1
if scale != 0 && p.arch.Family == sys.ARM64 {
if scale != 0 && scale != 1 && p.arch.Family == sys.ARM64 {
// Support (R1)(R2) (no scaling) and (R1)(R2*1).
p.errorf("arm64 doesn't support scaled register format")
} else {
a.Scale = int16(scale)

View file

@ -547,6 +547,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
// shifted or extended register offset.
MOVD (R2)(R6.SXTW), R4 // 44c866f8
MOVD (R3)(R6), R5 // 656866f8
MOVD (R3)(R6*1), R5 // 656866f8
MOVD (R2)(R6), R4 // 446866f8
MOVWU (R19)(R20<<2), R20 // 747a74b8
MOVD (R2)(R6<<3), R4 // 447866f8
@ -579,6 +580,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVB R4, (R2)(R6.SXTX) // 44e82638
MOVB R8, (R3)(R9.UXTW) // 68482938
MOVB R10, (R5)(R8) // aa682838
MOVB R10, (R5)(R8*1) // aa682838
MOVH R11, (R2)(R7.SXTW<<1) // 4bd82778
MOVH R5, (R1)(R2<<1) // 25782278
MOVH R7, (R2)(R5.SXTX<<1) // 47f82578

View file

@ -152,7 +152,7 @@ func lockVersion(mod module.Version) (unlock func(), err error) {
// If err is nil, the caller MUST eventually call the unlock function.
func SideLock() (unlock func(), err error) {
if err := checkCacheDir(); err != nil {
base.Fatalf("go: %v", err)
return nil, err
}
path := filepath.Join(cfg.GOMODCACHE, "cache", "lock")

View file

@ -1153,6 +1153,7 @@ func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPack
Tags: imports.AnyTags(),
VendorModulesInGOROOTSrc: true,
LoadTests: *getT,
AssumeRootsImported: true, // After 'go get foo', imports of foo should build.
SilencePackageErrors: true, // May be fixed by subsequent upgrades or downgrades.
}

View file

@ -443,7 +443,7 @@ func expandGraph(ctx context.Context, rs *Requirements) (*Requirements, *ModuleG
// roots — but in a lazy module it may pull in previously-irrelevant
// transitive dependencies.
newRS, rsErr := updateRoots(ctx, rs.direct, rs, nil, nil)
newRS, rsErr := updateRoots(ctx, rs.direct, rs, nil, nil, false)
if rsErr != nil {
// Failed to update roots, perhaps because of an error in a transitive
// dependency needed for the update. Return the original Requirements
@ -517,11 +517,11 @@ func tidyRoots(ctx context.Context, rs *Requirements, pkgs []*loadPkg) (*Require
return tidyLazyRoots(ctx, rs.direct, pkgs)
}
func updateRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version) (*Requirements, error) {
func updateRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error) {
if rs.depth == eager {
return updateEagerRoots(ctx, direct, rs, add)
}
return updateLazyRoots(ctx, direct, rs, pkgs, add)
return updateLazyRoots(ctx, direct, rs, pkgs, add, rootsImported)
}
// tidyLazyRoots returns a minimal set of root requirements that maintains the
@ -661,7 +661,7 @@ func tidyLazyRoots(ctx context.Context, direct map[string]bool, pkgs []*loadPkg)
//
// (See https://golang.org/design/36460-lazy-module-loading#invariants for more
// detail.)
func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version) (*Requirements, error) {
func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error) {
roots := rs.rootModules
rootsUpgraded := false
@ -688,6 +688,10 @@ func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requiremen
//
// (This is the “import invariant” that makes lazy loading possible.)
case rootsImported && pkg.flags.has(pkgFromRoot):
// pkg is a transitive dependency of some root, and we are treating the
// roots as if they are imported by the main module (as in 'go get').
case pkg.flags.has(pkgIsRoot):
// pkg is a root of the package-import graph. (Generally this means that
// it matches a command-line argument.) We want future invocations of the

View file

@ -661,7 +661,7 @@ func requirementsFromModFile(ctx context.Context) *Requirements {
for _, n := range mPathCount {
if n > 1 {
var err error
rs, err = updateRoots(ctx, rs.direct, rs, nil, nil)
rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
if err != nil {
base.Fatalf("go: %v", err)
}

View file

@ -171,6 +171,11 @@ type PackageOpts struct {
// if the flag is set to "readonly" (the default) or "vendor".
ResolveMissingImports bool
// AssumeRootsImported indicates that the transitive dependencies of the root
// packages should be treated as if those roots will be imported by the main
// module.
AssumeRootsImported bool
// AllowPackage, if non-nil, is called after identifying the module providing
// each package. If AllowPackage returns a non-nil error, that error is set
// for the package, and the imports and test of that package will not be
@ -875,6 +880,11 @@ const (
// are also roots (and must be marked pkgIsRoot).
pkgIsRoot
// pkgFromRoot indicates that the package is in the transitive closure of
// imports starting at the roots. (Note that every package marked as pkgIsRoot
// is also trivially marked pkgFromRoot.)
pkgFromRoot
// pkgImportsLoaded indicates that the imports and testImports fields of a
// loadPkg have been populated.
pkgImportsLoaded
@ -1068,7 +1078,7 @@ func loadFromRoots(ctx context.Context, params loaderParams) *loader {
// iteration so we don't need to also update it here. (That would waste time
// computing a "direct" map that we'll have to recompute later anyway.)
direct := ld.requirements.direct
rs, err := updateRoots(ctx, direct, ld.requirements, noPkgs, toAdd)
rs, err := updateRoots(ctx, direct, ld.requirements, noPkgs, toAdd, ld.AssumeRootsImported)
if err != nil {
// If an error was found in a newly added module, report the package
// import stack instead of the module requirement stack. Packages
@ -1274,7 +1284,7 @@ func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err err
addRoots = tidy.rootModules
}
rs, err = updateRoots(ctx, direct, rs, ld.pkgs, addRoots)
rs, err = updateRoots(ctx, direct, rs, ld.pkgs, addRoots, ld.AssumeRootsImported)
if err != nil {
// We don't actually know what even the root requirements are supposed to be,
// so we can't proceed with loading. Return the error to the caller
@ -1433,6 +1443,9 @@ func (ld *loader) applyPkgFlags(ctx context.Context, pkg *loadPkg, flags loadPkg
// This package matches a root pattern by virtue of being in "all".
flags |= pkgIsRoot
}
if flags.has(pkgIsRoot) {
flags |= pkgFromRoot
}
old := pkg.flags.update(flags)
new := old | flags
@ -1487,6 +1500,12 @@ func (ld *loader) applyPkgFlags(ctx context.Context, pkg *loadPkg, flags loadPkg
ld.applyPkgFlags(ctx, dep, pkgInAll)
}
}
if new.has(pkgFromRoot) && !old.has(pkgFromRoot|pkgImportsLoaded) {
for _, dep := range pkg.imports {
ld.applyPkgFlags(ctx, dep, pkgFromRoot)
}
}
}
// preloadRootModules loads the module requirements needed to identify the
@ -1549,7 +1568,7 @@ func (ld *loader) preloadRootModules(ctx context.Context, rootPkgs []string) (ch
}
module.Sort(toAdd)
rs, err := updateRoots(ctx, ld.requirements.direct, ld.requirements, nil, toAdd)
rs, err := updateRoots(ctx, ld.requirements.direct, ld.requirements, nil, toAdd, ld.AssumeRootsImported)
if err != nil {
// We are missing some root dependency, and for some reason we can't load
// enough of the module dependency graph to add the missing root. Package

View file

@ -0,0 +1,15 @@
# 'go mod edit' opportunistically locks the side-lock file in the module cache,
# for compatibility with older versions of the 'go' command.
# It does not otherwise depend on the module cache, so it should not
# fail if the module cache directory cannot be created.
[root] skip
mkdir $WORK/readonly
chmod 0555 $WORK/readonly
env GOPATH=$WORK/readonly/nonexist
go mod edit -go=1.17
-- go.mod --
module example.com/m

View file

@ -0,0 +1,44 @@
# https://golang.org/issue/45979: after 'go get' on a package,
# that package should be importable without error.
# We start out with an unresolved dependency.
# 'go list' suggests that we run 'go get' on that dependency.
! go list -deps .
stderr '^m.go:3:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc.io/quote$'
# When we run the suggested 'go get' command, the new dependency can be used
# immediately.
#
# 'go get' marks the new dependency as 'indirect', because it doesn't scan
# enough source code to know whether it is direct, and it is easier and less
# invasive to remove an incorrect indirect mark (e.g. using 'go get') than to
# add one that is missing ('go mod tidy' or 'go mod vendor').
go get rsc.io/quote
grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod
! grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod
go list -deps .
! stderr .
[!short] go build .
[!short] ! stderr .
# 'go get .' (or 'go mod tidy') removes the indirect mark.
go get .
grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod
! grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod
-- go.mod --
module example.com/m
go 1.17
-- m.go --
package m
import _ "rsc.io/quote"

View file

@ -10,45 +10,73 @@ go env GOSUMDB
stdout '^sum.golang.org$'
# Download direct from github.
[!net] skip
[!exec:git] skip
env GOSUMDB=sum.golang.org
env GOPROXY=direct
go get -d rsc.io/quote@v1.5.2
cp go.sum saved.sum
# Download from proxy.golang.org with go.sum entry already.
# Use 'go list' instead of 'go get' since the latter may download extra go.mod
# files not listed in go.sum.
go clean -modcache
env GOSUMDB=
env GOPROXY=
go list -x -deps rsc.io/quote
go list -x -m all # Download go.mod files.
! stderr github
stderr proxy.golang.org/rsc.io/quote
! stderr sum.golang.org/tile
! stderr sum.golang.org/lookup/rsc.io/quote
go list -x -deps rsc.io/quote # Download module source.
! 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.
# 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 list -mod=mod -x rsc.io/quote
go list -mod=mod -x -m all # Add checksums for go.mod files.
stderr sum.golang.org/tile
! stderr github
! stderr proxy.golang.org/rsc.io/quote
stderr sum.golang.org/tile
stderr sum.golang.org/lookup/rsc.io/quote
go list -mod=mod -x rsc.io/quote # Add checksums for module source.
! stderr . # Adds checksums, but for entities already in the module cache.
cmp go.sum saved.sum
# test fallback to direct
env TESTGOPROXY404=1
go clean -modcache
rm go.sum
go list -mod=mod -x rsc.io/quote
go list -mod=mod -x -m all # Download go.mod files
stderr 'proxy.golang.org.*404 testing'
stderr github.com/rsc
go list -mod=mod -x rsc.io/quote # Download module source.
stderr 'proxy.golang.org.*404 testing'
stderr github.com/rsc
cmp go.sum saved.sum
-- go.mod --
module m

View file

@ -233,8 +233,8 @@ func (f *file) Name() string {
}
func (f *file) ObjAddr(addr uint64) (uint64, error) {
// No support for shared libraries.
return 0, nil
// No support for shared libraries, so translation is a no-op.
return addr, nil
}
func (f *file) BuildID() string {

127
src/cmd/pprof/pprof_test.go Normal file
View file

@ -0,0 +1,127 @@
// 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 (
"fmt"
"internal/testenv"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
var tmp, pprofExe string // populated by buildPprof
func TestMain(m *testing.M) {
if !testenv.HasGoBuild() {
return
}
var exitcode int
if err := buildPprof(); err == nil {
exitcode = m.Run()
} else {
fmt.Println(err)
exitcode = 1
}
os.RemoveAll(tmp)
os.Exit(exitcode)
}
func buildPprof() error {
var err error
tmp, err = os.MkdirTemp("", "TestPprof")
if err != nil {
return fmt.Errorf("TempDir failed: %v", err)
}
pprofExe = filepath.Join(tmp, "testpprof.exe")
gotool, err := testenv.GoTool()
if err != nil {
return err
}
out, err := exec.Command(gotool, "build", "-o", pprofExe, "cmd/pprof").CombinedOutput()
if err != nil {
os.RemoveAll(tmp)
return fmt.Errorf("go build -o %v cmd/pprof: %v\n%s", pprofExe, err, string(out))
}
return nil
}
// See also runtime/pprof.cpuProfilingBroken.
func mustHaveCPUProfiling(t *testing.T) {
switch runtime.GOOS {
case "plan9":
t.Skipf("skipping on %s, unimplemented", runtime.GOOS)
case "aix":
t.Skipf("skipping on %s, issue 45170", runtime.GOOS)
case "ios", "dragonfly", "netbsd", "illumos", "solaris":
t.Skipf("skipping on %s, issue 13841", runtime.GOOS)
case "openbsd":
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
t.Skipf("skipping on %s/%s, issue 13841", runtime.GOOS, runtime.GOARCH)
}
}
}
func mustHaveDisasm(t *testing.T) {
switch runtime.GOARCH {
case "mips", "mipsle", "mips64", "mips64le":
t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
case "riscv64":
t.Skipf("skipping on %s, issue 36738", runtime.GOARCH)
case "s390x":
t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
}
// Skip PIE platforms, pprof can't disassemble PIE.
if runtime.GOOS == "windows" {
t.Skipf("skipping on %s, issue 46639", runtime.GOOS)
}
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
t.Skipf("skipping on %s/%s, issue 46639", runtime.GOOS, runtime.GOARCH)
}
}
// TestDisasm verifies that cmd/pprof can successfully disassemble functions.
//
// This is a regression test for issue 46636.
func TestDisasm(t *testing.T) {
mustHaveCPUProfiling(t)
mustHaveDisasm(t)
testenv.MustHaveGoBuild(t)
tmpdir := t.TempDir()
cpuExe := filepath.Join(tmpdir, "cpu.exe")
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", cpuExe, "cpu.go")
cmd.Dir = "testdata/"
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("build failed: %v\n%s", err, out)
}
profile := filepath.Join(tmpdir, "cpu.pprof")
cmd = exec.Command(cpuExe, "-output", profile)
out, err = cmd.CombinedOutput()
if err != nil {
t.Fatalf("cpu failed: %v\n%s", err, out)
}
cmd = exec.Command(pprofExe, "-disasm", "main.main", cpuExe, profile)
out, err = cmd.CombinedOutput()
if err != nil {
t.Fatalf("pprof failed: %v\n%s", err, out)
}
sout := string(out)
want := "ROUTINE ======================== main.main"
if !strings.Contains(sout, want) {
t.Errorf("pprof disasm got %s want contains %q", sout, want)
}
}

41
src/cmd/pprof/testdata/cpu.go vendored Normal file
View file

@ -0,0 +1,41 @@
// 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 (
"flag"
"fmt"
"os"
"runtime/pprof"
"time"
)
var output = flag.String("output", "", "pprof profile output file")
func main() {
flag.Parse()
if *output == "" {
fmt.Fprintf(os.Stderr, "usage: %s -output file.pprof\n", os.Args[0])
os.Exit(2)
}
f, err := os.Create(*output)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
defer pprof.StopCPUProfile()
// Spin for long enough to collect some samples.
start := time.Now()
for time.Since(start) < time.Second {
}
}

View file

@ -2838,9 +2838,10 @@ func TestTxStmtDeadlock(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tx, err := db.BeginTx(ctx, nil)
cancel()
if err != nil {
t.Fatal(err)
}

View file

@ -23,6 +23,16 @@ type Image interface {
Set(x, y int, c color.Color)
}
// RGBA64Image extends both the Image and image.RGBA64Image interfaces with a
// SetRGBA64 method to change a single pixel. SetRGBA64 is equivalent to
// calling Set, but it can avoid allocations from converting concrete color
// types to the color.Color interface type.
type RGBA64Image interface {
image.RGBA64Image
Set(x, y int, c color.Color)
SetRGBA64(x, y int, c color.RGBA64)
}
// Quantizer produces a palette for an image.
type Quantizer interface {
// Quantize appends up to cap(p) - len(p) colors to p and returns the

View file

@ -45,6 +45,17 @@ type Image interface {
At(x, y int) color.Color
}
// RGBA64Image is an Image whose pixels can be converted directly to a
// color.RGBA64.
type RGBA64Image interface {
// RGBA64At returns the RGBA64 color of the pixel at (x, y). It is
// equivalent to calling At(x, y).RGBA() and converting the resulting
// 32-bit return values to a color.RGBA64, but it can avoid allocations
// from converting concrete color types to the color.Color interface type.
RGBA64At(x, y int) color.RGBA64
Image
}
// PalettedImage is an image whose colors may come from a limited palette.
// If m is a PalettedImage and m.ColorModel() returns a color.Palette p,
// then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
@ -90,6 +101,24 @@ func (p *RGBA) At(x, y int) color.Color {
return p.RGBAAt(x, y)
}
func (p *RGBA) RGBA64At(x, y int) color.RGBA64 {
if !(Point{x, y}.In(p.Rect)) {
return color.RGBA64{}
}
i := p.PixOffset(x, y)
s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
r := uint16(s[0])
g := uint16(s[1])
b := uint16(s[2])
a := uint16(s[3])
return color.RGBA64{
(r << 8) | r,
(g << 8) | g,
(b << 8) | b,
(a << 8) | a,
}
}
func (p *RGBA) RGBAAt(x, y int) color.RGBA {
if !(Point{x, y}.In(p.Rect)) {
return color.RGBA{}
@ -118,6 +147,18 @@ func (p *RGBA) Set(x, y int, c color.Color) {
s[3] = c1.A
}
func (p *RGBA) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
i := p.PixOffset(x, y)
s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
s[0] = uint8(c.R >> 8)
s[1] = uint8(c.G >> 8)
s[2] = uint8(c.B >> 8)
s[3] = uint8(c.A >> 8)
}
func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -311,6 +352,11 @@ func (p *NRGBA) At(x, y int) color.Color {
return p.NRGBAAt(x, y)
}
func (p *NRGBA) RGBA64At(x, y int) color.RGBA64 {
r, g, b, a := p.NRGBAAt(x, y).RGBA()
return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
}
func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA {
if !(Point{x, y}.In(p.Rect)) {
return color.NRGBA{}
@ -339,6 +385,24 @@ func (p *NRGBA) Set(x, y int, c color.Color) {
s[3] = c1.A
}
func (p *NRGBA) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
r, g, b, a := uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
if (a != 0) && (a != 0xffff) {
r = (r * 0xffff) / a
g = (g * 0xffff) / a
b = (b * 0xffff) / a
}
i := p.PixOffset(x, y)
s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
s[0] = uint8(r >> 8)
s[1] = uint8(g >> 8)
s[2] = uint8(b >> 8)
s[3] = uint8(a >> 8)
}
func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -415,6 +479,11 @@ func (p *NRGBA64) At(x, y int) color.Color {
return p.NRGBA64At(x, y)
}
func (p *NRGBA64) RGBA64At(x, y int) color.RGBA64 {
r, g, b, a := p.NRGBA64At(x, y).RGBA()
return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
}
func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 {
if !(Point{x, y}.In(p.Rect)) {
return color.NRGBA64{}
@ -452,6 +521,28 @@ func (p *NRGBA64) Set(x, y int, c color.Color) {
s[7] = uint8(c1.A)
}
func (p *NRGBA64) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
r, g, b, a := uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
if (a != 0) && (a != 0xffff) {
r = (r * 0xffff) / a
g = (g * 0xffff) / a
b = (b * 0xffff) / a
}
i := p.PixOffset(x, y)
s := p.Pix[i : i+8 : i+8] // Small cap improves performance, see https://golang.org/issue/27857
s[0] = uint8(r >> 8)
s[1] = uint8(r)
s[2] = uint8(g >> 8)
s[3] = uint8(g)
s[4] = uint8(b >> 8)
s[5] = uint8(b)
s[6] = uint8(a >> 8)
s[7] = uint8(a)
}
func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -532,6 +623,12 @@ func (p *Alpha) At(x, y int) color.Color {
return p.AlphaAt(x, y)
}
func (p *Alpha) RGBA64At(x, y int) color.RGBA64 {
a := uint16(p.AlphaAt(x, y).A)
a |= a << 8
return color.RGBA64{a, a, a, a}
}
func (p *Alpha) AlphaAt(x, y int) color.Alpha {
if !(Point{x, y}.In(p.Rect)) {
return color.Alpha{}
@ -554,6 +651,14 @@ func (p *Alpha) Set(x, y int, c color.Color) {
p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
}
func (p *Alpha) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
i := p.PixOffset(x, y)
p.Pix[i] = uint8(c.A >> 8)
}
func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -626,6 +731,11 @@ func (p *Alpha16) At(x, y int) color.Color {
return p.Alpha16At(x, y)
}
func (p *Alpha16) RGBA64At(x, y int) color.RGBA64 {
a := p.Alpha16At(x, y).A
return color.RGBA64{a, a, a, a}
}
func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 {
if !(Point{x, y}.In(p.Rect)) {
return color.Alpha16{}
@ -650,6 +760,15 @@ func (p *Alpha16) Set(x, y int, c color.Color) {
p.Pix[i+1] = uint8(c1.A)
}
func (p *Alpha16) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
i := p.PixOffset(x, y)
p.Pix[i+0] = uint8(c.A >> 8)
p.Pix[i+1] = uint8(c.A)
}
func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -723,6 +842,12 @@ func (p *Gray) At(x, y int) color.Color {
return p.GrayAt(x, y)
}
func (p *Gray) RGBA64At(x, y int) color.RGBA64 {
gray := uint16(p.GrayAt(x, y).Y)
gray |= gray << 8
return color.RGBA64{gray, gray, gray, 0xffff}
}
func (p *Gray) GrayAt(x, y int) color.Gray {
if !(Point{x, y}.In(p.Rect)) {
return color.Gray{}
@ -745,6 +870,16 @@ func (p *Gray) Set(x, y int, c color.Color) {
p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
}
func (p *Gray) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
// This formula is the same as in color.grayModel.
gray := (19595*uint32(c.R) + 38470*uint32(c.G) + 7471*uint32(c.B) + 1<<15) >> 24
i := p.PixOffset(x, y)
p.Pix[i] = uint8(gray)
}
func (p *Gray) SetGray(x, y int, c color.Gray) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -804,6 +939,11 @@ func (p *Gray16) At(x, y int) color.Color {
return p.Gray16At(x, y)
}
func (p *Gray16) RGBA64At(x, y int) color.RGBA64 {
gray := p.Gray16At(x, y).Y
return color.RGBA64{gray, gray, gray, 0xffff}
}
func (p *Gray16) Gray16At(x, y int) color.Gray16 {
if !(Point{x, y}.In(p.Rect)) {
return color.Gray16{}
@ -828,6 +968,17 @@ func (p *Gray16) Set(x, y int, c color.Color) {
p.Pix[i+1] = uint8(c1.Y)
}
func (p *Gray16) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
// This formula is the same as in color.gray16Model.
gray := (19595*uint32(c.R) + 38470*uint32(c.G) + 7471*uint32(c.B) + 1<<15) >> 16
i := p.PixOffset(x, y)
p.Pix[i+0] = uint8(gray >> 8)
p.Pix[i+1] = uint8(gray)
}
func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -888,6 +1039,11 @@ func (p *CMYK) At(x, y int) color.Color {
return p.CMYKAt(x, y)
}
func (p *CMYK) RGBA64At(x, y int) color.RGBA64 {
r, g, b, a := p.CMYKAt(x, y).RGBA()
return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
}
func (p *CMYK) CMYKAt(x, y int) color.CMYK {
if !(Point{x, y}.In(p.Rect)) {
return color.CMYK{}
@ -916,6 +1072,19 @@ func (p *CMYK) Set(x, y int, c color.Color) {
s[3] = c1.K
}
func (p *CMYK) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
cc, mm, yy, kk := color.RGBToCMYK(uint8(c.R>>8), uint8(c.G>>8), uint8(c.B>>8))
i := p.PixOffset(x, y)
s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
s[0] = cc
s[1] = mm
s[2] = yy
s[3] = kk
}
func (p *CMYK) SetCMYK(x, y int, c color.CMYK) {
if !(Point{x, y}.In(p.Rect)) {
return
@ -988,6 +1157,26 @@ func (p *Paletted) At(x, y int) color.Color {
return p.Palette[p.Pix[i]]
}
func (p *Paletted) RGBA64At(x, y int) color.RGBA64 {
if len(p.Palette) == 0 {
return color.RGBA64{}
}
c := color.Color(nil)
if !(Point{x, y}.In(p.Rect)) {
c = p.Palette[0]
} else {
i := p.PixOffset(x, y)
c = p.Palette[p.Pix[i]]
}
r, g, b, a := c.RGBA()
return color.RGBA64{
uint16(r),
uint16(g),
uint16(b),
uint16(a),
}
}
// PixOffset returns the index of the first element of Pix that corresponds to
// the pixel at (x, y).
func (p *Paletted) PixOffset(x, y int) int {
@ -1002,6 +1191,14 @@ func (p *Paletted) Set(x, y int, c color.Color) {
p.Pix[i] = uint8(p.Palette.Index(c))
}
func (p *Paletted) SetRGBA64(x, y int, c color.RGBA64) {
if !(Point{x, y}.In(p.Rect)) {
return
}
i := p.PixOffset(x, y)
p.Pix[i] = uint8(p.Palette.Index(c))
}
func (p *Paletted) ColorIndexAt(x, y int) uint8 {
if !(Point{x, y}.In(p.Rect)) {
return 0

View file

@ -6,6 +6,7 @@ package image
import (
"image/color"
"image/color/palette"
"testing"
)
@ -191,6 +192,80 @@ func Test16BitsPerColorChannel(t *testing.T) {
}
}
func TestRGBA64Image(t *testing.T) {
// memset sets every element of s to v.
memset := func(s []byte, v byte) {
for i := range s {
s[i] = v
}
}
r := Rect(0, 0, 3, 2)
testCases := []Image{
NewAlpha(r),
NewAlpha16(r),
NewCMYK(r),
NewGray(r),
NewGray16(r),
NewNRGBA(r),
NewNRGBA64(r),
NewNYCbCrA(r, YCbCrSubsampleRatio444),
NewPaletted(r, palette.Plan9),
NewRGBA(r),
NewRGBA64(r),
NewYCbCr(r, YCbCrSubsampleRatio444),
}
for _, tc := range testCases {
switch tc := tc.(type) {
// Most of the concrete image types in the testCases implement the
// draw.RGBA64Image interface: they have a SetRGBA64 method. We use an
// interface literal here, instead of importing "image/draw", to avoid
// an import cycle.
//
// The YCbCr and NYCbCrA types are special-cased. Chroma subsampling
// means that setting one pixel can modify neighboring pixels. They
// don't have Set or SetRGBA64 methods because that side effect could
// be surprising. Here, we just memset the channel buffers instead.
case interface {
SetRGBA64(x, y int, c color.RGBA64)
}:
tc.SetRGBA64(1, 1, color.RGBA64{0x7FFF, 0x3FFF, 0x0000, 0x7FFF})
case *NYCbCrA:
memset(tc.YCbCr.Y, 0x77)
memset(tc.YCbCr.Cb, 0x88)
memset(tc.YCbCr.Cr, 0x99)
memset(tc.A, 0xAA)
case *YCbCr:
memset(tc.Y, 0x77)
memset(tc.Cb, 0x88)
memset(tc.Cr, 0x99)
default:
t.Errorf("could not initialize pixels for %T", tc)
continue
}
// Check that RGBA64At(x, y) is equivalent to At(x, y).RGBA().
rgba64Image, ok := tc.(RGBA64Image)
if !ok {
t.Errorf("%T is not an RGBA64Image", tc)
continue
}
got := rgba64Image.RGBA64At(1, 1)
wantR, wantG, wantB, wantA := tc.At(1, 1).RGBA()
if (uint32(got.R) != wantR) || (uint32(got.G) != wantG) ||
(uint32(got.B) != wantB) || (uint32(got.A) != wantA) {
t.Errorf("%T:\ngot (0x%04X, 0x%04X, 0x%04X, 0x%04X)\n"+
"want (0x%04X, 0x%04X, 0x%04X, 0x%04X)", tc,
got.R, got.G, got.B, got.A,
wantR, wantG, wantB, wantA)
continue
}
}
}
func BenchmarkAt(b *testing.B) {
for _, tc := range testImages {
b.Run(tc.name, func(b *testing.B) {

View file

@ -71,6 +71,11 @@ func (p *YCbCr) At(x, y int) color.Color {
return p.YCbCrAt(x, y)
}
func (p *YCbCr) RGBA64At(x, y int) color.RGBA64 {
r, g, b, a := p.YCbCrAt(x, y).RGBA()
return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
}
func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr {
if !(Point{x, y}.In(p.Rect)) {
return color.YCbCr{}
@ -210,6 +215,11 @@ func (p *NYCbCrA) At(x, y int) color.Color {
return p.NYCbCrAAt(x, y)
}
func (p *NYCbCrA) RGBA64At(x, y int) color.RGBA64 {
r, g, b, a := p.NYCbCrAAt(x, y).RGBA()
return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
}
func (p *NYCbCrA) NYCbCrAAt(x, y int) color.NYCbCrA {
if !(Point{X: x, Y: y}.In(p.Rect)) {
return color.NYCbCrA{}

View file

@ -12,9 +12,6 @@
// The default Source is safe for concurrent use by multiple goroutines, but
// Sources created by NewSource are not.
//
// Mathematical interval notation such as [0, n) is used throughout the
// documentation for this package.
//
// This package's outputs might be easily predictable regardless of how it's
// seeded. For random numbers suitable for security-sensitive work, see the
// crypto/rand package.
@ -106,7 +103,7 @@ func (r *Rand) Int() int {
return int(u << 1 >> 1) // clear sign bit if int == int32
}
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
func (r *Rand) Int63n(n int64) int64 {
if n <= 0 {
@ -123,7 +120,7 @@ func (r *Rand) Int63n(n int64) int64 {
return v % n
}
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
func (r *Rand) Int31n(n int32) int32 {
if n <= 0 {
@ -140,7 +137,7 @@ func (r *Rand) Int31n(n int32) int32 {
return v % n
}
// int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
// n must be > 0, but int31n does not check this; the caller must ensure it.
// int31n exists because Int31n is inefficient, but Go 1 compatibility
// requires that the stream of values produced by math/rand remain unchanged.
@ -164,7 +161,7 @@ func (r *Rand) int31n(n int32) int32 {
return int32(prod >> 32)
}
// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
// It panics if n <= 0.
func (r *Rand) Intn(n int) int {
if n <= 0 {
@ -176,7 +173,7 @@ func (r *Rand) Intn(n int) int {
return int(r.Int63n(int64(n)))
}
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
func (r *Rand) Float64() float64 {
// A clearer, simpler implementation would be:
// return float64(r.Int63n(1<<53)) / (1<<53)
@ -202,7 +199,7 @@ again:
return f
}
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
func (r *Rand) Float32() float32 {
// Same rationale as in Float64: we want to preserve the Go 1 value
// stream except we want to fix it not to return 1.0
@ -215,7 +212,8 @@ again:
return f
}
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
// in the half-open interval [0,n).
func (r *Rand) Perm(n int) []int {
m := make([]int, n)
// In the following loop, the iteration when i=0 always swaps m[0] with m[0].
@ -323,31 +321,31 @@ func Int31() int32 { return globalRand.Int31() }
// Int returns a non-negative pseudo-random int from the default Source.
func Int() int { return globalRand.Int() }
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n)
// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n)
// from the default Source.
// It panics if n <= 0.
func Int63n(n int64) int64 { return globalRand.Int63n(n) }
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n)
// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n)
// from the default Source.
// It panics if n <= 0.
func Int31n(n int32) int32 { return globalRand.Int31n(n) }
// Intn returns, as an int, a non-negative pseudo-random number in [0,n)
// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n)
// from the default Source.
// It panics if n <= 0.
func Intn(n int) int { return globalRand.Intn(n) }
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0)
// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0)
// from the default Source.
func Float64() float64 { return globalRand.Float64() }
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0)
// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0)
// from the default Source.
func Float32() float32 { return globalRand.Float32() }
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n)
// from the default Source.
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
// in the half-open interval [0,n) from the default Source.
func Perm(n int) []int { return globalRand.Perm(n) }
// Shuffle pseudo-randomizes the order of elements using the default Source.

View file

@ -32,6 +32,11 @@ import (
// The current value is set based on flakes observed in the Go builders.
var settleTime = 100 * time.Millisecond
// fatalWaitingTime is an absurdly long time to wait for signals to be
// delivered but, using it, we (hopefully) eliminate test flakes on the
// build servers. See #46736 for discussion.
var fatalWaitingTime = 30 * time.Second
func init() {
if testenv.Builder() == "solaris-amd64-oraclerel" {
// The solaris-amd64-oraclerel builder has been observed to time out in
@ -84,7 +89,7 @@ func waitSig1(t *testing.T, c <-chan os.Signal, sig os.Signal, all bool) {
// General user code should filter out all unexpected signals instead of just
// SIGURG, but since os/signal is tightly coupled to the runtime it seems
// appropriate to be stricter here.
for time.Since(start) < settleTime {
for time.Since(start) < fatalWaitingTime {
select {
case s := <-c:
if s == sig {
@ -97,7 +102,7 @@ func waitSig1(t *testing.T, c <-chan os.Signal, sig os.Signal, all bool) {
timer.Reset(settleTime / 10)
}
}
t.Fatalf("timeout after %v waiting for %v", settleTime, sig)
t.Fatalf("timeout after %v waiting for %v", fatalWaitingTime, sig)
}
// quiesce waits until we can be reasonably confident that all pending signals

View file

@ -12,12 +12,15 @@ import (
func ExampleFrames() {
c := func() {
// Ask runtime.Callers for up to 10 pcs, including runtime.Callers itself.
// Ask runtime.Callers for up to 10 PCs, including runtime.Callers itself.
pc := make([]uintptr, 10)
n := runtime.Callers(0, pc)
if n == 0 {
// No pcs available. Stop now.
// This can happen if the first argument to runtime.Callers is large.
// No PCs available. This can happen if the first argument to
// runtime.Callers is large.
//
// Return now to avoid processing the zero Frame that would
// otherwise be returned by frames.Next below.
return
}
@ -25,9 +28,12 @@ func ExampleFrames() {
frames := runtime.CallersFrames(pc)
// Loop to get frames.
// A fixed number of pcs can expand to an indefinite number of Frames.
// A fixed number of PCs can expand to an indefinite number of Frames.
for {
frame, more := frames.Next()
// Process this frame.
//
// To keep this example's output stable
// even if there are changes in the testing package,
// stop unwinding when we leave package runtime.
@ -35,6 +41,8 @@ func ExampleFrames() {
break
}
fmt.Printf("- more:%v | %s\n", more, frame.Function)
// Check whether there are more frames to process after this one.
if !more {
break
}

View file

@ -261,6 +261,27 @@ func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Loca
return p
}
func cpuProfilingBroken() bool {
switch runtime.GOOS {
case "plan9":
// Profiling unimplemented.
return true
case "aix":
// See https://golang.org/issue/45170.
return true
case "ios", "dragonfly", "netbsd", "illumos", "solaris":
// See https://golang.org/issue/13841.
return true
case "openbsd":
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
// See https://golang.org/issue/13841.
return true
}
}
return false
}
// testCPUProfile runs f under the CPU profiler, checking for some conditions specified by need,
// as interpreted by matches, and returns the parsed profile.
func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []string, f func(dur time.Duration)) *profile.Profile {
@ -276,16 +297,7 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri
t.Skip("skipping on plan9")
}
broken := false
switch runtime.GOOS {
// See https://golang.org/issue/45170 for AIX.
case "ios", "dragonfly", "netbsd", "illumos", "solaris", "aix":
broken = true
case "openbsd":
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
broken = true
}
}
broken := cpuProfilingBroken()
maxDuration := 5 * time.Second
if testing.Short() && broken {
@ -612,7 +624,7 @@ func growstack1() {
//go:noinline
func growstack(n int) {
var buf [8 << 16]byte
var buf [8 << 18]byte
use(buf)
if n > 0 {
growstack(n - 1)
@ -620,7 +632,7 @@ func growstack(n int) {
}
//go:noinline
func use(x [8 << 16]byte) {}
func use(x [8 << 18]byte) {}
func TestBlockProfile(t *testing.T) {
type TestCase struct {

View file

@ -281,6 +281,8 @@ func setProcessCPUProfiler(hz int32) {
it.it_value = it.it_interval
setitimer(_ITIMER_PROF, &it, nil)
} else {
setitimer(_ITIMER_PROF, &itimerval{}, nil)
// If the Go signal handler should be disabled by default,
// switch back to the signal handler that was installed
// when we enabled profiling. We don't try to handle the case
@ -304,8 +306,6 @@ func setProcessCPUProfiler(hz int32) {
setsig(_SIGPROF, h)
}
}
setitimer(_ITIMER_PROF, &itimerval{}, nil)
}
}
@ -383,7 +383,7 @@ func preemptM(mp *m) {
//go:nosplit
func sigFetchG(c *sigctxt) *g {
switch GOARCH {
case "arm", "arm64":
case "arm", "arm64", "ppc64", "ppc64le":
if !iscgo && inVDSOPage(c.sigpc()) {
// When using cgo, we save the g on TLS and load it from there
// in sigtramp. Just use that.

View file

@ -69,8 +69,15 @@ func CallersFrames(callers []uintptr) *Frames {
return f
}
// Next returns frame information for the next caller.
// If more is false, there are no more callers (the Frame value is valid).
// Next returns a Frame representing the next call frame in the slice
// of PC values. If it has already returned all call frames, Next
// returns a zero Frame.
//
// The more result indicates whether the next call to Next will return
// a valid Frame. It does not necessarily indicate whether this call
// returned one.
//
// See the Frames example for idiomatic usage.
func (ci *Frames) Next() (frame Frame, more bool) {
for len(ci.frames) < 2 {
// Find the next frame.

View file

@ -216,15 +216,45 @@ TEXT runtime·walltime(SB),NOSPLIT,$16-12
MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
noswitch:
SUB $16, R1 // Space for results
RLDICR $0, R1, $59, R1 // Align for C code
SUB $16, R1 // Space for results
RLDICR $0, R1, $59, R1 // Align for C code
MOVD R12, CTR
MOVD R1, R4
BL (CTR) // Call from VDSO
MOVD $0, R0 // Restore R0
MOVD 0(R1), R3 // sec
MOVD 8(R1), R5 // nsec
MOVD R15, R1 // Restore SP
// Store g on gsignal's stack, so if we receive a signal
// during VDSO code we can find the g.
// If we don't have a signal stack, we won't receive signal,
// so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
// Also don't save g if we are already on the signal stack.
// We won't get a nested signal.
MOVBZ runtime·iscgo(SB), R22
CMP R22, $0
BNE nosaveg
MOVD m_gsignal(R21), R22 // g.m.gsignal
CMP R22, $0
BEQ nosaveg
CMP g, R22
BEQ nosaveg
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
MOVD g, (R22)
BL (CTR) // Call from VDSO
MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
JMP finish
nosaveg:
BL (CTR) // Call from VDSO
finish:
MOVD $0, R0 // Restore R0
MOVD 0(R1), R3 // sec
MOVD 8(R1), R5 // nsec
MOVD R15, R1 // Restore SP
// Restore vdsoPC, vdsoSP
// We don't worry about being signaled between the two stores.
@ -236,7 +266,7 @@ noswitch:
MOVD 32(R1), R6
MOVD R6, m_vdsoPC(R21)
finish:
return:
MOVD R3, sec+0(FP)
MOVW R5, nsec+8(FP)
RET
@ -247,7 +277,7 @@ fallback:
SYSCALL $SYS_clock_gettime
MOVD 32(R1), R3
MOVD 40(R1), R5
JMP finish
JMP return
TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
MOVD $1, R3 // CLOCK_MONOTONIC
@ -283,7 +313,37 @@ noswitch:
RLDICR $0, R1, $59, R1 // Align for C code
MOVD R12, CTR
MOVD R1, R4
BL (CTR) // Call from VDSO
// Store g on gsignal's stack, so if we receive a signal
// during VDSO code we can find the g.
// If we don't have a signal stack, we won't receive signal,
// so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
// Also don't save g if we are already on the signal stack.
// We won't get a nested signal.
MOVBZ runtime·iscgo(SB), R22
CMP R22, $0
BNE nosaveg
MOVD m_gsignal(R21), R22 // g.m.gsignal
CMP R22, $0
BEQ nosaveg
CMP g, R22
BEQ nosaveg
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
MOVD g, (R22)
BL (CTR) // Call from VDSO
MOVD $0, (R22) // clear g slot, R22 is unchanged by C code
JMP finish
nosaveg:
BL (CTR) // Call from VDSO
finish:
MOVD $0, R0 // Restore R0
MOVD 0(R1), R3 // sec
MOVD 8(R1), R5 // nsec
@ -299,7 +359,7 @@ noswitch:
MOVD 32(R1), R6
MOVD R6, m_vdsoPC(R21)
finish:
return:
// sec is in R3, nsec in R5
// return nsec in R3
MOVD $1000000000, R4
@ -314,7 +374,7 @@ fallback:
SYSCALL $SYS_clock_gettime
MOVD 32(R1), R3
MOVD 40(R1), R5
JMP finish
JMP return
TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
MOVW how+0(FP), R3
@ -469,7 +529,7 @@ TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
// this might be called in external code context,
// where g is not set.
MOVBZ runtime·iscgo(SB), R6
CMP R6, $0
CMP R6, $0
BEQ 2(PC)
BL runtime·load_g(SB)

View file

@ -252,6 +252,8 @@ import (
"sync"
"sync/atomic"
"time"
"unicode"
"unicode/utf8"
)
var initRan bool
@ -908,11 +910,6 @@ func (c *common) Cleanup(f func()) {
c.cleanups = append(c.cleanups, fn)
}
var tempDirReplacer struct {
sync.Once
r *strings.Replacer
}
// TempDir returns a temporary directory for the test to use.
// The directory is automatically removed by Cleanup when the test and
// all its subtests complete.
@ -936,13 +933,26 @@ func (c *common) TempDir() string {
if nonExistent {
c.Helper()
// os.MkdirTemp doesn't like path separators in its pattern,
// so mangle the name to accommodate subtests.
tempDirReplacer.Do(func() {
tempDirReplacer.r = strings.NewReplacer("/", "_", "\\", "_", ":", "_")
})
pattern := tempDirReplacer.r.Replace(c.Name())
// Drop unusual characters (such as path separators or
// characters interacting with globs) from the directory name to
// avoid surprising os.MkdirTemp behavior.
mapper := func(r rune) rune {
if r < utf8.RuneSelf {
const allowed = "!#$%&()+,-.=@^_{}~ "
if '0' <= r && r <= '9' ||
'a' <= r && r <= 'z' ||
'A' <= r && r <= 'Z' {
return r
}
if strings.ContainsRune(allowed, r) {
return r
}
} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
return r
}
return -1
}
pattern := strings.Map(mapper, c.Name())
c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
if c.tempDirErr == nil {
c.Cleanup(func() {

View file

@ -58,6 +58,9 @@ func TestTempDir(t *testing.T) {
t.Run("test:subtest", testTempDir)
t.Run("test/..", testTempDir)
t.Run("../test", testTempDir)
t.Run("test[]", testTempDir)
t.Run("test*", testTempDir)
t.Run("äöüéè", testTempDir)
}
func testTempDir(t *testing.T) {
@ -74,7 +77,7 @@ func testTempDir(t *testing.T) {
if err != nil {
t.Fatal(err)
}
t.Errorf("directory %q stil exists: %v, isDir=%v", dir, fi, fi.IsDir())
t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
default:
if !t.Failed() {
t.Fatal("never received dir channel")
@ -108,6 +111,11 @@ func testTempDir(t *testing.T) {
if len(files) > 0 {
t.Errorf("unexpected %d files in TempDir: %v", len(files), files)
}
glob := filepath.Join(dir, "*.txt")
if _, err := filepath.Glob(glob); err != nil {
t.Error(err)
}
}
func TestSetenv(t *testing.T) {

View file

@ -1340,7 +1340,7 @@ func UnixMicro(usec int64) Time {
}
// IsDST reports whether the time in the configured location is in Daylight Savings Time.
func (t *Time) IsDST() bool {
func (t Time) IsDST() bool {
_, _, _, _, isDST := t.loc.lookup(t.Unix())
return isDST
}