diff --git a/doc/go1.17.html b/doc/go1.17.html index 35d0f974502..75c05c9e255 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -59,7 +59,7 @@ Do not send CLs removing the interior tags from such phrases.

- These enhancements were added to simplify writing code that conforms + The package unsafe enhancements were added to simplify writing code that conforms to unsafe.Pointer's safety rules, but the rules remain unchanged. In particular, existing programs that correctly use unsafe.Pointer remain @@ -292,6 +292,18 @@ Do not send CLs removing the interior tags from such phrases. https://golang.org/design/draft-gobuild.

+

go run

+ +

+ go run now accepts arguments with version suffixes + (for example, go run + example.com/cmd@v1.0.0). This causes go + run to build and run packages in module-aware mode, ignoring the + go.mod file in the current directory or any parent directory, if + there is one. This is useful for running executables without installing them or + without changing dependencies of the current module. +

+

Gofmt

@@ -406,7 +418,8 @@ func Foo() bool { by commas. Aggregate-typed (struct, array, string, slice, interface, and complex) arguments are delimited by curly braces. A caveat is that the value of an argument that only lives in a register and is not stored to memory may be - inaccurate. Results (which were usually inaccurate) are no longer printed. + inaccurate. Function return values (which were usually inaccurate) are no longer + printed.

@@ -734,7 +747,7 @@ func Foo() bool { These components were always interpreted as decimal, but some operating systems treat them as octal. This mismatch could hypothetically lead to security issues if a Go application was used to validate IP addresses which were then used in their original form with non-Go applications which interpreted components as octal. Generally, - it is advisable to always re-encoded values after validation, which avoids this class of parser misalignment issues. + it is advisable to always re-encode values after validation, which avoids this class of parser misalignment issues.

@@ -785,7 +798,7 @@ func Foo() bool {

The File.WriteString method - has been optimized to no longer make a copy of the input string. + has been optimized to not make a copy of the input string.

@@ -811,6 +824,14 @@ func Foo() bool { The ArrayOf function now panics when called with a negative length.

+ +

+ Checking the Type.ConvertibleTo method + is no longer sufficient to guarantee that a call to + Value.Convert will not panic. + It may panic when converting `[]T` to `*[N]T` if the slice's length is less than N. + See the language changes section above. +

@@ -837,7 +858,7 @@ func Foo() bool {

The strconv package now uses Ulf Adams's Ryū algorithm for formatting floating-point numbers. - This algorithm improves performance on most inputs, and is more than 99% faster on worst-case inputs. + This algorithm improves performance on most inputs and is more than 99% faster on worst-case inputs.

diff --git a/src/cmd/compile/internal/typecheck/const.go b/src/cmd/compile/internal/typecheck/const.go index 5a35eeade9f..761b0437940 100644 --- a/src/cmd/compile/internal/typecheck/const.go +++ b/src/cmd/compile/internal/typecheck/const.go @@ -633,6 +633,17 @@ func defaultlit2(l ir.Node, r ir.Node, force bool) (ir.Node, ir.Node) { if l.Type() == nil || r.Type() == nil { return l, r } + + if !l.Type().IsInterface() && !r.Type().IsInterface() { + // Can't mix bool with non-bool, string with non-string. + if l.Type().IsBoolean() != r.Type().IsBoolean() { + return l, r + } + if l.Type().IsString() != r.Type().IsString() { + return l, r + } + } + if !l.Type().IsUntyped() { r = convlit(r, l.Type()) return l, r @@ -647,17 +658,10 @@ func defaultlit2(l ir.Node, r ir.Node, force bool) (ir.Node, ir.Node) { return l, r } - // Can't mix bool with non-bool, string with non-string, or nil with anything (untyped). - if l.Type().IsBoolean() != r.Type().IsBoolean() { - return l, r - } - if l.Type().IsString() != r.Type().IsString() { - return l, r - } + // Can't mix nil with anything untyped. if ir.IsNil(l) || ir.IsNil(r) { return l, r } - t := defaultType(mixUntyped(l.Type(), r.Type())) l = convlit(l, t) r = convlit(r, t) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 1ed2c0f631e..f2c4cf0b430 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -1057,7 +1057,7 @@ func (t *tester) supportedBuildmode(mode string) bool { "darwin-amd64", "darwin-arm64", "freebsd-amd64", "android-arm", "android-arm64", "android-386", - "windows-amd64", "windows-386": + "windows-amd64", "windows-386", "windows-arm64": return true } return false diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index ab61017c4eb..3febe880cdd 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -1568,7 +1568,7 @@ // // A build constraint, also known as a build tag, is a line comment that begins // -// // +build +// //go:build // // that lists the conditions under which a file should be included in the package. // Constraints may appear in any kind of source file (not just Go), but @@ -1576,30 +1576,20 @@ // only by blank lines and other line comments. These rules mean that in Go // files a build constraint must appear before the package clause. // -// To distinguish build constraints from package documentation, a series of -// build constraints must be followed by a blank line. +// To distinguish build constraints from package documentation, +// a build constraint should be followed by a blank line. // -// A build constraint is evaluated as the OR of space-separated options. -// Each option evaluates as the AND of its comma-separated terms. -// Each term consists of letters, digits, underscores, and dots. -// A term may be negated with a preceding !. -// For example, the build constraint: +// A build constraint is evaluated as an expression containing options +// combined by ||, &&, and ! operators and parentheses. Operators have +// the same meaning as in Go. // -// // +build linux,386 darwin,!cgo +// For example, the following build constraint constrains a file to +// build when the "linux" and "386" constraints are satisfied, or when +// "darwin" is satisfied and "cgo" is not: // -// corresponds to the boolean formula: +// //go:build (linux && 386) || (darwin && !cgo) // -// (linux AND 386) OR (darwin AND (NOT cgo)) -// -// A file may have multiple build constraints. The overall constraint is the AND -// of the individual constraints. That is, the build constraints: -// -// // +build linux darwin -// // +build amd64 -// -// corresponds to the boolean formula: -// -// (linux OR darwin) AND amd64 +// It is an error for a file to have more than one //go:build line. // // During a particular build, the following words are satisfied: // @@ -1637,24 +1627,28 @@ // // To keep a file from being considered for the build: // -// // +build ignore +// //go:build ignore // // (any other unsatisfied word will work as well, but "ignore" is conventional.) // // To build a file only when using cgo, and only on Linux and OS X: // -// // +build linux,cgo darwin,cgo +// //go:build cgo && (linux || darwin) // // Such a file is usually paired with another file implementing the // default functionality for other systems, which in this case would // carry the constraint: // -// // +build !linux,!darwin !cgo +// //go:build !(cgo && (linux || darwin)) // // Naming a file dns_windows.go will cause it to be included only when // building the package for Windows; similarly, math_386.s will be included // only when building the package for 32-bit x86. // +// Go versions 1.16 and earlier used a different syntax for build constraints, +// with a "// +build" prefix. The gofmt command will add an equivalent //go:build +// constraint when encountering the older syntax. +// // // Build modes // diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go index 2f86e4195d9..9ec65018926 100644 --- a/src/cmd/go/internal/help/helpdoc.go +++ b/src/cmd/go/internal/help/helpdoc.go @@ -784,7 +784,7 @@ var HelpBuildConstraint = &base.Command{ Long: ` A build constraint, also known as a build tag, is a line comment that begins - // +build + //go:build that lists the conditions under which a file should be included in the package. Constraints may appear in any kind of source file (not just Go), but @@ -792,30 +792,20 @@ they must appear near the top of the file, preceded only by blank lines and other line comments. These rules mean that in Go files a build constraint must appear before the package clause. -To distinguish build constraints from package documentation, a series of -build constraints must be followed by a blank line. +To distinguish build constraints from package documentation, +a build constraint should be followed by a blank line. -A build constraint is evaluated as the OR of space-separated options. -Each option evaluates as the AND of its comma-separated terms. -Each term consists of letters, digits, underscores, and dots. -A term may be negated with a preceding !. -For example, the build constraint: +A build constraint is evaluated as an expression containing options +combined by ||, &&, and ! operators and parentheses. Operators have +the same meaning as in Go. - // +build linux,386 darwin,!cgo +For example, the following build constraint constrains a file to +build when the "linux" and "386" constraints are satisfied, or when +"darwin" is satisfied and "cgo" is not: -corresponds to the boolean formula: + //go:build (linux && 386) || (darwin && !cgo) - (linux AND 386) OR (darwin AND (NOT cgo)) - -A file may have multiple build constraints. The overall constraint is the AND -of the individual constraints. That is, the build constraints: - - // +build linux darwin - // +build amd64 - -corresponds to the boolean formula: - - (linux OR darwin) AND amd64 +It is an error for a file to have more than one //go:build line. During a particular build, the following words are satisfied: @@ -853,22 +843,26 @@ in addition to ios tags and files. To keep a file from being considered for the build: - // +build ignore + //go:build ignore (any other unsatisfied word will work as well, but "ignore" is conventional.) To build a file only when using cgo, and only on Linux and OS X: - // +build linux,cgo darwin,cgo + //go:build cgo && (linux || darwin) Such a file is usually paired with another file implementing the default functionality for other systems, which in this case would carry the constraint: - // +build !linux,!darwin !cgo + //go:build !(cgo && (linux || darwin)) Naming a file dns_windows.go will cause it to be included only when building the package for Windows; similarly, math_386.s will be included only when building the package for 32-bit x86. + +Go versions 1.16 and earlier used a different syntax for build constraints, +with a "// +build" prefix. The gofmt command will add an equivalent //go:build +constraint when encountering the older syntax. `, } diff --git a/src/cmd/go/internal/imports/read.go b/src/cmd/go/internal/imports/read.go index 5e270781d77..70d51904505 100644 --- a/src/cmd/go/internal/imports/read.go +++ b/src/cmd/go/internal/imports/read.go @@ -8,6 +8,7 @@ package imports import ( "bufio" + "bytes" "errors" "io" "unicode/utf8" @@ -22,6 +23,19 @@ type importReader struct { nerr int } +var bom = []byte{0xef, 0xbb, 0xbf} + +func newImportReader(b *bufio.Reader) *importReader { + // Remove leading UTF-8 BOM. + // Per https://golang.org/ref/spec#Source_code_representation: + // a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF) + // if it is the first Unicode code point in the source text. + if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) { + b.Discard(3) + } + return &importReader{b: b} +} + func isIdent(c byte) bool { return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf } @@ -201,7 +215,7 @@ func (r *importReader) readImport(imports *[]string) { // ReadComments is like io.ReadAll, except that it only reads the leading // block of comments in the file. func ReadComments(f io.Reader) ([]byte, error) { - r := &importReader{b: bufio.NewReader(f)} + r := newImportReader(bufio.NewReader(f)) r.peekByte(true) if r.err == nil && !r.eof { // Didn't reach EOF, so must have found a non-space byte. Remove it. @@ -213,7 +227,7 @@ func ReadComments(f io.Reader) ([]byte, error) { // ReadImports is like io.ReadAll, except that it expects a Go file as input // and stops reading the input once the imports have completed. func ReadImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) { - r := &importReader{b: bufio.NewReader(f)} + r := newImportReader(bufio.NewReader(f)) r.readKeyword("package") r.readIdent() diff --git a/src/cmd/go/internal/imports/read_test.go b/src/cmd/go/internal/imports/read_test.go index 6ea356f1ff0..6a1a6524a11 100644 --- a/src/cmd/go/internal/imports/read_test.go +++ b/src/cmd/go/internal/imports/read_test.go @@ -66,6 +66,10 @@ var readImportsTests = []readTest{ `, "", }, + { + "\ufeffš¯”»" + `package p; import "x";ā„™var x = 1`, + "", + }, } var readCommentsTests = []readTest{ @@ -81,6 +85,10 @@ var readCommentsTests = []readTest{ `ā„™package p; import . "x"`, "", }, + { + "\ufeffš¯”»" + `ā„™package p; import . "x"`, + "", + }, { `// foo @@ -90,6 +98,19 @@ var readCommentsTests = []readTest{ /*/ zot */ + // asdf + ā„™Hello, world`, + "", + }, + { + "\ufeffš¯”»" + `// foo + + /* bar */ + + /* quux */ // baz + + /*/ zot */ + // asdf ā„™Hello, world`, "", @@ -107,6 +128,11 @@ func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, erro in = tt.in[:j] + tt.in[j+len("ā„™"):] testOut = tt.in[:j] } + d := strings.Index(tt.in, "š¯”»") + if d >= 0 { + in = in[:d] + in[d+len("š¯”»"):] + testOut = testOut[d+len("š¯”»"):] + } r := strings.NewReader(in) buf, err := read(r) if err != nil { diff --git a/src/cmd/go/testdata/script/build_ignore_leading_bom.txt b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt new file mode 100644 index 00000000000..37141f3466b --- /dev/null +++ b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt @@ -0,0 +1,27 @@ +# Per https://golang.org/ref/spec#Source_code_representation: +# a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF) +# if it is the first Unicode code point in the source text. + +go list -f 'Imports: {{.Imports}} EmbedFiles: {{.EmbedFiles}}' . +stdout '^Imports: \[embed m/hello\] EmbedFiles: \[.*file\]$' + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +ļ»æpackage main + +import ( + _ "embed" + + "m/hello" +) + +//go:embed file +var s string + +-- hello/hello.go -- +package hello + +-- file -- diff --git a/src/cmd/internal/sys/supported.go b/src/cmd/internal/sys/supported.go index fa477b837ff..0d2bad96127 100644 --- a/src/cmd/internal/sys/supported.go +++ b/src/cmd/internal/sys/supported.go @@ -74,7 +74,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", "darwin/amd64", "darwin/arm64", - "windows/amd64", "windows/386": + "windows/amd64", "windows/386", "windows/arm64": return true } return false diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 6f81e74da29..81011638bc5 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -950,6 +950,11 @@ func elfdynhash(ctxt *Link) { } s = ldr.CreateSymForUpdate(".dynamic", 0) + if ctxt.BuildMode == BuildModePIE { + // https://github.com/bminor/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/elf/elf.h#L986 + const DTFLAGS_1_PIE = 0x08000000 + Elfwritedynent(ctxt.Arch, s, elf.DT_FLAGS_1, uint64(DTFLAGS_1_PIE)) + } elfverneed = nfile if elfverneed != 0 { elfWriteDynEntSym(ctxt, s, elf.DT_VERNEED, gnuVersionR.Sym()) diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go index cd5bf8fab00..b25d8209e36 100644 --- a/src/debug/elf/file.go +++ b/src/debug/elf/file.go @@ -1164,6 +1164,13 @@ func (f *File) DWARF() (*dwarf.Data, error) { b = dbuf } + if f.Type == ET_EXEC { + // Do not apply relocations to DWARF sections for ET_EXEC binaries. + // Relocations should already be applied, and .rela sections may + // contain incorrect data. + return b, nil + } + for _, r := range f.Sections { if r.Type != SHT_RELA && r.Type != SHT_REL { continue diff --git a/src/go/build/doc.go b/src/go/build/doc.go index 2c6f0a83bea..778b4f40f7c 100644 --- a/src/go/build/doc.go +++ b/src/go/build/doc.go @@ -59,7 +59,7 @@ // // A build constraint, also known as a build tag, is a line comment that begins // -// // +build +// //go:build // // that lists the conditions under which a file should be included in the // package. Build constraints may also be part of a file's name diff --git a/src/go/build/read.go b/src/go/build/read.go index aa7c6ee59eb..b98c7938a85 100644 --- a/src/go/build/read.go +++ b/src/go/build/read.go @@ -6,6 +6,7 @@ package build import ( "bufio" + "bytes" "errors" "fmt" "go/ast" @@ -28,9 +29,19 @@ type importReader struct { pos token.Position } +var bom = []byte{0xef, 0xbb, 0xbf} + func newImportReader(name string, r io.Reader) *importReader { + b := bufio.NewReader(r) + // Remove leading UTF-8 BOM. + // Per https://golang.org/ref/spec#Source_code_representation: + // a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF) + // if it is the first Unicode code point in the source text. + if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) { + b.Discard(3) + } return &importReader{ - b: bufio.NewReader(r), + b: b, pos: token.Position{ Filename: name, Line: 1, diff --git a/src/go/build/read_test.go b/src/go/build/read_test.go index 32e6bae0088..1e5e1c2de2e 100644 --- a/src/go/build/read_test.go +++ b/src/go/build/read_test.go @@ -66,6 +66,10 @@ var readGoInfoTests = []readTest{ `, "", }, + { + "\ufeffš¯”»" + `package p; import "x";ā„™var x = 1`, + "", + }, } var readCommentsTests = []readTest{ @@ -81,6 +85,10 @@ var readCommentsTests = []readTest{ `ā„™package p; import . "x"`, "", }, + { + "\ufeffš¯”»" + `ā„™package p; import . "x"`, + "", + }, { `// foo @@ -90,6 +98,19 @@ var readCommentsTests = []readTest{ /*/ zot */ + // asdf + ā„™Hello, world`, + "", + }, + { + "\ufeffš¯”»" + `// foo + + /* bar */ + + /* quux */ // baz + + /*/ zot */ + // asdf ā„™Hello, world`, "", @@ -107,6 +128,11 @@ func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, erro in = tt.in[:j] + tt.in[j+len("ā„™"):] testOut = tt.in[:j] } + d := strings.Index(tt.in, "š¯”»") + if d >= 0 { + in = in[:d] + in[d+len("š¯”»"):] + testOut = testOut[d+len("š¯”»"):] + } r := strings.NewReader(in) buf, err := read(r) if err != nil { @@ -264,6 +290,12 @@ var readEmbedTests = []struct { test:3:14:y test:3:16:z`, }, + { + "\ufeffpackage p\nimport \"embed\"\n//go:embed x y z\nvar files embed.FS", + `test:3:12:x + test:3:14:y + test:3:16:z`, + }, { "package p\nimport \"embed\"\nvar s = \"/*\"\n//go:embed x\nvar files embed.FS", `test:4:12:x`, @@ -292,6 +324,10 @@ var readEmbedTests = []struct { "package p\n//go:embed x y z\nvar files embed.FS", // no import, no scan "", }, + { + "\ufeffpackage p\n//go:embed x y z\nvar files embed.FS", // no import, no scan + "", + }, } func TestReadEmbed(t *testing.T) { diff --git a/src/internal/bytealg/index_generic.go b/src/internal/bytealg/index_generic.go index 287bdba4c68..0a6eb90d2d9 100644 --- a/src/internal/bytealg/index_generic.go +++ b/src/internal/bytealg/index_generic.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64 //go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64 // +build !amd64,!arm64,!s390x,!ppc64le,!ppc64 diff --git a/src/internal/bytealg/index_native.go b/src/internal/bytealg/index_native.go index 75aff4b3cb0..9547a5d8e2a 100644 --- a/src/internal/bytealg/index_native.go +++ b/src/internal/bytealg/index_native.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// go:build amd64 || arm64 || s390x || ppc64le || ppc64 //go:build amd64 || arm64 || s390x || ppc64le || ppc64 // +build amd64 arm64 s390x ppc64le ppc64 diff --git a/src/net/http/server.go b/src/net/http/server.go index 50fab4520dd..5b113cff970 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -333,7 +333,7 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) { const bufferBeforeChunkingSize = 2048 // chunkWriter writes to a response's conn buffer, and is the writer -// wrapped by the response.bufw buffered writer. +// wrapped by the response.w buffered writer. // // chunkWriter also is responsible for finalizing the Header, including // conditionally setting the Content-Type and setting a Content-Length @@ -1529,12 +1529,12 @@ func (w *response) bodyAllowed() bool { // The Writers are wired together like: // // 1. *response (the ResponseWriter) -> -// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes +// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes -> // 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type) -// and which writes the chunk headers, if needed. -// 4. conn.buf, a bufio.Writer of default (4kB) bytes, writing to -> +// and which writes the chunk headers, if needed -> +// 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to -> // 5. checkConnErrorWriter{c}, which notes any non-nil error on Write -// and populates c.werr with it if so. but otherwise writes to: +// and populates c.werr with it if so, but otherwise writes to -> // 6. the rwc, the net.Conn. // // TODO(bradfitz): short-circuit some of the buffering when the diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 17104ad4fab..0db5e132172 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -4371,7 +4371,7 @@ func TestConvertPanic(t *testing.T) { if !v.Type().ConvertibleTo(pt) { t.Errorf("[]byte should be convertible to *[8]byte") } - shouldPanic("reflect: cannot convert slice with length 4 to array pointer with length 8", func() { + shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() { _ = v.Convert(pt) }) } diff --git a/src/reflect/type.go b/src/reflect/type.go index 39414fc2a64..df863ae106f 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -107,10 +107,14 @@ type Type interface { // ConvertibleTo reports whether a value of the type is convertible to type u. // Even if ConvertibleTo returns true, the conversion may still panic. + // For example, a slice of type []T is convertible to *[N]T, + // but the conversion will panic if its length is less than N. ConvertibleTo(u Type) bool // Comparable reports whether values of this type are comparable. // Even if Comparable returns true, the comparison may still panic. + // For example, values of interface type are comparable, + // but the comparison will panic if their dynamic type is not comparable. Comparable() bool // Methods applicable only to some types, depending on Kind. diff --git a/src/reflect/value.go b/src/reflect/value.go index c963a407bcc..6ba6202a1a1 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -3067,7 +3067,7 @@ func cvtSliceArrayPtr(v Value, t Type) Value { n := t.Elem().Len() h := (*unsafeheader.Slice)(v.ptr) if n > h.Len { - panic("reflect: cannot convert slice with length " + itoa.Itoa(h.Len) + " to array pointer with length " + itoa.Itoa(n)) + panic("reflect: cannot convert slice with length " + itoa.Itoa(h.Len) + " to pointer to array with length " + itoa.Itoa(n)) } return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Ptr)} } diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 4a116130a54..e4268b71090 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -516,8 +516,8 @@ var ( allglock mutex allgs []*g - // allglen and allgptr are atomic variables that contain len(allg) and - // &allg[0] respectively. Proper ordering depends on totally-ordered + // allglen and allgptr are atomic variables that contain len(allgs) and + // &allgs[0] respectively. Proper ordering depends on totally-ordered // loads and stores. Writes are protected by allglock. // // allgptr is updated before allglen. Readers should read allglen diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go index 7d89eaae63a..85b59ad00d9 100644 --- a/src/syscall/exec_linux_test.go +++ b/src/syscall/exec_linux_test.go @@ -318,6 +318,7 @@ func TestGroupCleanupUserNamespace(t *testing.T) { "uid=0(root) gid=0(root) groups=0(root),65534", "uid=0(root) gid=0(root) groups=0(root),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody)", // Alpine; see https://golang.org/issue/19938 "uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023", // CentOS with SELinux context, see https://golang.org/issue/34547 + "uid=0(root) gid=0(root) groups=0(root),65534(nobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023", // Fedora with SElinux context, see https://golang.org/issue/46752 } for _, e := range expected { if strOut == e { diff --git a/src/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go index 3243952ded1..194c87805cd 100644 --- a/src/syscall/syscall_windows_test.go +++ b/src/syscall/syscall_windows_test.go @@ -10,7 +10,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "syscall" "testing" @@ -79,10 +78,8 @@ func TestTOKEN_ALL_ACCESS(t *testing.T) { func TestStdioAreInheritable(t *testing.T) { testenv.MustHaveGoBuild(t) + testenv.MustHaveCGO(t) testenv.MustHaveExecPath(t, "gcc") - if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { - t.Skip("Powershell is not native on ARM; see golang.org/issues/46701") - } tmpdir := t.TempDir() @@ -114,18 +111,28 @@ func main() {} t.Fatalf("failed to build go library: %s\n%s", err, out) } - // run powershell script - psscript := fmt.Sprintf(` -hostname; -$signature = " [DllImport("%q")] public static extern void HelloWorld(); "; -Add-Type -MemberDefinition $signature -Name World -Namespace Hello; -[Hello.World]::HelloWorld(); -hostname; -`, dll) - psscript = strings.ReplaceAll(psscript, "\n", "") - out, err = exec.Command("powershell", "-Command", psscript).CombinedOutput() + // build c exe + const exetext = ` +#include +#include +int main(int argc, char *argv[]) +{ + system("hostname"); + ((void(*)(void))GetProcAddress(LoadLibraryA(%q), "HelloWorld"))(); + system("hostname"); + return 0; +} +` + exe := filepath.Join(tmpdir, "helloworld.exe") + cmd = exec.Command("gcc", "-o", exe, "-xc", "-") + cmd.Stdin = strings.NewReader(fmt.Sprintf(exetext, dll)) + out, err = testenv.CleanCmdEnv(cmd).CombinedOutput() if err != nil { - t.Fatalf("Powershell command failed: %v: %v", err, string(out)) + t.Fatalf("failed to build c executable: %s\n%s", err, out) + } + out, err = exec.Command(exe).CombinedOutput() + if err != nil { + t.Fatalf("c program execution failed: %v: %v", err, string(out)) } hostname, err := os.Hostname() @@ -137,6 +144,6 @@ hostname; have = strings.ReplaceAll(have, "\r", "") want := fmt.Sprintf("%sHello World%s", hostname, hostname) if have != want { - t.Fatalf("Powershell command output is wrong: got %q, want %q", have, want) + t.Fatalf("c program output is wrong: got %q, want %q", have, want) } } diff --git a/test/fixedbugs/issue46749.go b/test/fixedbugs/issue46749.go new file mode 100644 index 00000000000..63ed19795e5 --- /dev/null +++ b/test/fixedbugs/issue46749.go @@ -0,0 +1,37 @@ +// errorcheck + +// 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 p + +var s string +var b bool +var i int +var iface interface{} + +var ( + _ = "" + b // ERROR "invalid operation.*mismatched types.*untyped string and bool" + _ = "" + i // ERROR "invalid operation.*mismatched types.*untyped string and int" + _ = "" + nil // ERROR "invalid operation.*mismatched types.*untyped string and nil" +) + +var ( + _ = s + false // ERROR "invalid operation.*mismatched types.*string and untyped bool" + _ = s + 1 // ERROR "invalid operation.*mismatched types.*string and untyped int" + _ = s + nil // ERROR "invalid operation.*mismatched types.*string and nil" +) + +var ( + _ = "" + false // ERROR "invalid operation.*mismatched types.*untyped string and untyped bool" + _ = "" + 1 // ERROR "invalid operation.*mismatched types.*untyped string and untyped int" +) + +var ( + _ = b + 1 // ERROR "invalid operation.*mismatched types.*bool and untyped int" + _ = i + false // ERROR "invalid operation.*mismatched types.*int and untyped bool" + _ = iface + 1 // ERROR "invalid operation.*mismatched types.*interface {} and int" + _ = iface + 1.0 // ERROR "invalid operation.*mismatched types.*interface {} and float64" + _ = iface + false // ERROR "invalid operation.*mismatched types.*interface {} and bool" +) diff --git a/test/run.go b/test/run.go index 656519e3017..1273b8edd6b 100644 --- a/test/run.go +++ b/test/run.go @@ -2089,6 +2089,7 @@ var excludedFiles = map[string]bool{ "fixedbugs/issue7525d.go": true, // types2 reports init cycle error on different line - ok otherwise "fixedbugs/issue7525e.go": true, // types2 reports init cycle error on different line - ok otherwise "fixedbugs/issue7525.go": true, // types2 reports init cycle error on different line - ok otherwise + "fixedbugs/issue46749.go": true, // types2 reports can not convert error instead of type mismatched "fixedbugs/issue9691.go": true, // "cannot assign to int(.autotmp_4)" (probably irgen's fault) // tests that rely on -m diagnostics, which currently differ with -G=3