Update to go1.24.0

This commit is contained in:
Vorapol Rinsatitnon
2025-02-14 12:42:07 +07:00
parent 25e497e367
commit bf266cebe6
3169 changed files with 236789 additions and 60275 deletions

View File

@@ -18,7 +18,7 @@ type I4 interface { // GC_ERROR "invalid recursive type: I4 refers to itself"
I4 // GCCGO_ERROR "interface"
}
type I5 interface { // GC_ERROR "invalid recursive type I5\n\tLINE:.* I5 refers to\n\tLINE+4:.* I6 refers to\n\tLINE:.* I5$"
type I5 interface { // GC_ERROR "invalid recursive type I5\n\tLINE:.* I5 refers to I6\n\tLINE+4:.* I6 refers to I5$"
I6
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
package main
import "runtime"
func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|mixed named and unnamed|undefined identifier"
func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|missing parameter name|undefined identifier"
println(i, runtime.UintType) // GCCGO_ERROR "undefined identifier"
}

View File

@@ -10,7 +10,7 @@
package a
var? // ERROR "invalid character U\+003F '\?'|invalid character 0x3f in input file"
var x int // ERROR "unexpected var|expected identifier|expected type"
var x int // ERROR "unexpected keyword var|expected identifier|expected type"
func main() {
}

View File

@@ -0,0 +1,79 @@
// errorcheck -0 -m -l
// Copyright 2023 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 foo
import "sync/atomic"
func AddInt32(x *int32) { // ERROR "x does not escape$"
atomic.AddInt32(x, 42)
}
func AddUint32(x *uint32) { // ERROR "x does not escape$"
atomic.AddUint32(x, 42)
}
func AddUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.AddUintptr(x, 42)
}
func AndInt32(x *int32) { // ERROR "x does not escape$"
atomic.AndInt32(x, 42)
}
func AndUint32(x *uint32) { // ERROR "x does not escape$"
atomic.AndUint32(x, 42)
}
func AndUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.AndUintptr(x, 42)
}
func CompareAndSwapInt32(x *int32) { // ERROR "x does not escape$"
atomic.CompareAndSwapInt32(x, 42, 42)
}
func CompareAndSwapUint32(x *uint32) { // ERROR "x does not escape$"
atomic.CompareAndSwapUint32(x, 42, 42)
}
func CompareAndSwapUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.CompareAndSwapUintptr(x, 42, 42)
}
func LoadInt32(x *int32) { // ERROR "x does not escape$"
atomic.LoadInt32(x)
}
func LoadUint32(x *uint32) { // ERROR "x does not escape$"
atomic.LoadUint32(x)
}
func LoadUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.LoadUintptr(x)
}
func OrInt32(x *int32) { // ERROR "x does not escape$"
atomic.OrInt32(x, 42)
}
func OrUint32(x *uint32) { // ERROR "x does not escape$"
atomic.OrUint32(x, 42)
}
func OrUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.OrUintptr(x, 42)
}
func StoreInt32(x *int32) { // ERROR "x does not escape$"
atomic.StoreInt32(x, 42)
}
func StoreUint32(x *uint32) { // ERROR "x does not escape$"
atomic.StoreUint32(x, 42)
}
func StoreUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.StoreUintptr(x, 42)
}
func SwapInt32(x *int32) { // ERROR "x does not escape$"
atomic.SwapInt32(x, 42)
}
func SwapUint32(x *uint32) { // ERROR "x does not escape$"
atomic.SwapUint32(x, 42)
}
func SwapUintptr(x *uintptr) { // ERROR "x does not escape$"
atomic.SwapUintptr(x, 42)
}

View File

@@ -0,0 +1,60 @@
//go:build !(386 || arm || mips || mipsle)
// errorcheck -0 -m -l
// Copyright 2023 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 foo
import "sync/atomic"
func AddInt64(x *int64) { // ERROR "x does not escape$"
atomic.AddInt64(x, 42)
}
func AddUint64(x *uint64) { // ERROR "x does not escape$"
atomic.AddUint64(x, 42)
}
func AndInt64(x *int64) { // ERROR "x does not escape$"
atomic.AndInt64(x, 42)
}
func AndUint64(x *uint64) { // ERROR "x does not escape$"
atomic.AndUint64(x, 42)
}
func CompareAndSwapInt64(x *int64) { // ERROR "x does not escape$"
atomic.CompareAndSwapInt64(x, 42, 42)
}
func CompareAndSwapUint64(x *uint64) { // ERROR "x does not escape$"
atomic.CompareAndSwapUint64(x, 42, 42)
}
func LoadInt64(x *int64) { // ERROR "x does not escape$"
atomic.LoadInt64(x)
}
func LoadUint64(x *uint64) { // ERROR "x does not escape$"
atomic.LoadUint64(x)
}
func OrInt64(x *int64) { // ERROR "x does not escape$"
atomic.OrInt64(x, 42)
}
func OrUint64(x *uint64) { // ERROR "x does not escape$"
atomic.OrUint64(x, 42)
}
func StoreInt64(x *int64) { // ERROR "x does not escape$"
atomic.StoreInt64(x, 42)
}
func StoreUint64(x *uint64) { // ERROR "x does not escape$"
atomic.StoreUint64(x, 42)
}
func SwapInt64(x *int64) { // ERROR "x does not escape$"
atomic.SwapInt64(x, 42)
}
func SwapUint64(x *uint64) { // ERROR "x does not escape$"
atomic.SwapUint64(x, 42)
}

View File

@@ -0,0 +1,13 @@
// errorcheck
// Copyright 2024 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 _ chan [0x2FFFF]byte // ERROR "channel element type too large"
var _ = make(chan [0x2FFFF]byte) // ERROR "channel element type too large"
var c1 chan [0x2FFFF]byte // ERROR "channel element type too large"
var c2 = make(chan [0x2FFFF]byte) // ERROR "channel element type too large"

View File

@@ -0,0 +1,19 @@
// errorcheck
// Copyright 2024 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
type I interface {
F()
}
type T struct {
}
const _ = I((*T)(nil)) // ERROR "is not constant"
func (*T) F() {
}

View File

@@ -27,3 +27,12 @@ func z() {
z := t{&i}.f // ERROR "t{...}.f escapes to heap"
z()
}
// Should match cmd/compile/internal/ir/cfg.go:MaxStackVarSize.
const maxStack = 128 * 1024
func w(i int) byte {
var x [maxStack]byte
var y [maxStack + 1]byte // ERROR "moved to heap: y"
return x[i] + y[i]
}

View File

@@ -6,7 +6,7 @@
package p
type T1 struct { // ERROR "invalid recursive type T1\n\tLINE: T1 refers to\n\tLINE+4: T2 refers to\n\tLINE: T1$|invalid recursive type"
type T1 struct { // ERROR "invalid recursive type T1\n.*T1 refers to T2\n.*T2 refers to T1|invalid recursive type"
f2 T2
}
@@ -15,21 +15,21 @@ type T2 struct { // GCCGO_ERROR "invalid recursive type"
}
type a b // GCCGO_ERROR "invalid recursive type"
type b c // ERROR "invalid recursive type b\n\tLINE: b refers to\n\tLINE+1: c refers to\n\tLINE: b$|invalid recursive type"
type b c // ERROR "invalid recursive type b\n.*b refers to c\n.*c refers to b|invalid recursive type|invalid recursive type"
type c b // GCCGO_ERROR "invalid recursive type"
type d e
type e f
type f f // ERROR "invalid recursive type f\n\tLINE: f refers to\n\tLINE: f$|invalid recursive type"
type f f // ERROR "invalid recursive type: f refers to itself|invalid recursive type|invalid recursive type"
type g struct { // ERROR "invalid recursive type g\n\tLINE: g refers to\n\tLINE: g$|invalid recursive type"
type g struct { // ERROR "invalid recursive type: g refers to itself|invalid recursive type"
h struct {
g
}
}
type w x
type x y // ERROR "invalid recursive type x\n\tLINE: x refers to\n\tLINE+1: y refers to\n\tLINE+2: z refers to\n\tLINE: x$|invalid recursive type"
type x y // ERROR "invalid recursive type x\n.*x refers to y\n.*y refers to z\n.*z refers to x|invalid recursive type"
type y struct{ z } // GCCGO_ERROR "invalid recursive type"
type z [10]x

View File

@@ -51,6 +51,6 @@ func g() {
_ = i.(T6) // ERROR "impossible type assertion: i.\(T6\)\n\tT6 does not implement I \(missing method M\)\n\t\thave m\(int\) string\n\t\twant M\(int\)"
var t *T4
t = i // ERROR "cannot use i \(variable of type I\) as \*T4 value in assignment: need type assertion"
t = i // ERROR "cannot use i \(variable of interface type I\) as \*T4 value in assignment: need type assertion"
_ = t
}

View File

@@ -6,4 +6,4 @@ package b
import "./a"
type T a.T[T] // ERROR "invalid recursive type T\n.*T refers to\n.*a\.T refers to\n.*T"
type T a.T[T] // ERROR "invalid recursive type T\n.*T refers to a\.T\n.*a\.T refers to T"

View File

@@ -6,27 +6,6 @@
package p
import (
"crypto/ecdh"
"crypto/rand"
)
func F(peerShare []byte) ([]byte, error) { // ERROR "leaking param: peerShare"
p256 := ecdh.P256() // ERROR "inlining call to ecdh.P256"
ourKey, err := p256.GenerateKey(rand.Reader) // ERROR "devirtualizing p256.GenerateKey" "inlining call to ecdh.*GenerateKey"
if err != nil {
return nil, err
}
peerPublic, err := p256.NewPublicKey(peerShare) // ERROR "devirtualizing p256.NewPublicKey" "inlining call to ecdh.*NewPublicKey"
if err != nil {
return nil, err
}
return ourKey.ECDH(peerPublic)
}
// Test that inlining doesn't break if devirtualization exposes a new
// inlinable callee.

View File

@@ -11,6 +11,7 @@ func run() { // ERROR "cannot inline run: recursive"
g() // ERROR "inlining call to g"
}
f() // ERROR "inlining call to run.func1" "inlining call to g"
_ = f
run()
}

View File

@@ -0,0 +1,27 @@
// errorcheck -0 -d=ssa/check_bce/debug=1
// Copyright 2024 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 x
func Found(x []string) string {
switch len(x) {
default:
return x[0]
case 0, 1:
return ""
}
}
func NotFound(x []string) string {
switch len(x) {
default:
return x[0]
case 0:
return ""
case 1:
return ""
}
}

View File

@@ -0,0 +1,12 @@
// errorcheck
// Copyright 2024 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
func f[S any, T any](T) {}
func g() {
f(0) // ERROR "in call to f, cannot infer S \(declared at issue68292.go:9:8\)"
}

View File

@@ -0,0 +1,16 @@
// Copyright 2024 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.
//go:build goexperiment.aliastypeparams
package a
type A[T any] = struct{ F T }
type B = struct{ F int }
func F() B {
type a[T any] = struct{ F T }
return a[int]{}
}

View File

@@ -0,0 +1,45 @@
// Copyright 2024 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.
//go:build goexperiment.aliastypeparams
package main
import (
"fmt"
"issue68526.dir/a"
)
func main() {
unexported()
exported()
}
func unexported() {
var want struct{ F int }
if any(want) != any(a.B{}) || any(want) != any(a.F()) {
panic("zero value of alias and concrete type not identical")
}
}
func exported() {
var (
astr a.A[string]
aint a.A[int]
)
if any(astr) != any(struct{ F string }{}) || any(aint) != any(struct{ F int }{}) {
panic("zero value of alias and concrete type not identical")
}
if any(astr) == any(aint) {
panic("zero value of struct{ F string } and struct{ F int } are not distinct")
}
if got := fmt.Sprintf("%T", astr); got != "struct { F string }" {
panic(got)
}
}

View File

@@ -0,0 +1,7 @@
// runindir -goexperiment aliastypeparams -gomodversion "1.23"
// Copyright 2024 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

View File

@@ -0,0 +1,17 @@
// compile
// Copyright 2024 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.
// The gofrontend had a bug handling panic of an untyped constant expression.
package issue68734
func F1() {
panic(1 + 2)
}
func F2() {
panic("a" + "b")
}

View File

@@ -0,0 +1,19 @@
// run
// Copyright 2024 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
func main() {
cnt := 0
for i := 1; i <= 11; i++ {
if i-6 > 4 {
cnt++
}
}
if cnt != 1 {
panic("bad")
}
}

View File

@@ -0,0 +1,41 @@
// run
// Copyright 2024 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
func main() {
mustPanic(func() {
f1(1)
})
f2(1, 0) // must not panic
mustPanic(func() {
f2(1, 2)
})
}
var v []func()
//go:noinline
func f1(i int) {
v = make([]func(), -2|i)
}
//go:noinline
func f2(i, j int) {
if j > 0 {
v = make([]func(), -2|i)
}
}
func mustPanic(f func()) {
defer func() {
r := recover()
if r == nil {
panic("didn't panic")
}
}()
f()
}

View File

@@ -1,5 +1,7 @@
// run
//go:build !goexperiment.swissmap
// Copyright 2024 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.

View File

@@ -7,167 +7,55 @@
package main
import (
"bufio"
"fmt"
"io"
"iter"
"math/rand"
"os"
"strings"
"unicode"
)
// WordReader is the struct that implements io.Reader
type WordReader struct {
scanner *bufio.Scanner
}
// NewWordReader creates a new WordReader from an io.Reader
func NewWordReader(r io.Reader) *WordReader {
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanWords)
return &WordReader{
scanner: scanner,
}
}
// Read reads data from the input stream and returns a single lowercase word at a time
func (wr *WordReader) Read(p []byte) (n int, err error) {
if !wr.scanner.Scan() {
if err := wr.scanner.Err(); err != nil {
return 0, err
}
return 0, io.EOF
}
word := wr.scanner.Text()
cleanedWord := removeNonAlphabetic(word)
if len(cleanedWord) == 0 {
return wr.Read(p)
}
n = copy(p, []byte(cleanedWord))
return n, nil
}
// All returns an iterator allowing the caller to iterate over the WordReader using for/range.
func (wr *WordReader) All() iter.Seq[string] {
word := make([]byte, 1024)
return func(yield func(string) bool) {
var err error
var n int
for n, err = wr.Read(word); err == nil; n, err = wr.Read(word) {
if !yield(string(word[:n])) {
func All() iter.Seq[int] {
return func(yield func(int) bool) {
for i := 0; i < 10; i++ {
growStack(512)
if !yield(i) {
return
}
}
if err != io.EOF {
fmt.Fprintf(os.Stderr, "error reading word: %v\n", err)
}
}
}
// removeNonAlphabetic removes non-alphabetic characters from a word using strings.Map
func removeNonAlphabetic(word string) string {
return strings.Map(func(r rune) rune {
if unicode.IsLetter(r) {
return unicode.ToLower(r)
}
return -1
}, word)
type S struct {
round int
}
// ProbabilisticSkipper determines if an item should be retained with probability 1/(1<<n)
type ProbabilisticSkipper struct {
n int
counter uint64
bitmask uint64
func NewS(round int) *S {
s := &S{round: round}
return s
}
// NewProbabilisticSkipper initializes the ProbabilisticSkipper
func NewProbabilisticSkipper(n int) *ProbabilisticSkipper {
pr := &ProbabilisticSkipper{n: n}
pr.refreshCounter()
return pr
}
// check panics if pr.n is not the expected value
func (pr *ProbabilisticSkipper) check(n int) {
if pr.n != n {
panic(fmt.Sprintf("check: pr.n != n %d != %d", pr.n, n))
func (s *S) check(round int) {
if s.round != round {
panic("bad round")
}
}
// refreshCounter refreshes the counter with a new random value
func (pr *ProbabilisticSkipper) refreshCounter() {
if pr.n == 0 {
pr.bitmask = ^uint64(0) // All bits set to 1
} else {
pr.bitmask = rand.Uint64()
for i := 0; i < pr.n-1; i++ {
pr.bitmask &= rand.Uint64()
}
}
pr.counter = 64
}
// ShouldSkip returns true with probability 1/(1<<n)
func (pr *ProbabilisticSkipper) ShouldSkip() bool {
remove := pr.bitmask&1 == 0
pr.bitmask >>= 1
pr.counter--
if pr.counter == 0 {
pr.refreshCounter()
}
return remove
}
// EstimateUniqueWordsIter estimates the number of unique words using a probabilistic counting method
func EstimateUniqueWordsIter(reader io.Reader, memorySize int) int {
wordReader := NewWordReader(reader)
words := make(map[string]struct{}, memorySize)
func f() {
rounds := 0
roundRemover := NewProbabilisticSkipper(1)
wordSkipper := NewProbabilisticSkipper(rounds)
wordSkipper.check(rounds)
s := NewS(rounds)
s.check(rounds)
for word := range wordReader.All() {
wordSkipper.check(rounds)
if wordSkipper.ShouldSkip() {
delete(words, word)
} else {
words[word] = struct{}{}
if len(words) >= memorySize {
rounds++
wordSkipper = NewProbabilisticSkipper(rounds)
for w := range words {
if roundRemover.ShouldSkip() {
delete(words, w)
}
}
}
}
wordSkipper.check(rounds)
for range All() {
s.check(rounds)
rounds++
s = NewS(rounds)
s.check(rounds)
}
}
if len(words) == 0 {
return 0
func growStack(i int) {
if i == 0 {
return
}
invProbability := 1 << rounds
estimatedUniqueWords := len(words) * invProbability
return estimatedUniqueWords
growStack(i - 1)
}
func main() {
input := "Hello, world! This is a test. Hello, world, hello!"
expectedUniqueWords := 6 // "hello", "world", "this", "is", "a", "test" (but "hello" and "world" are repeated)
memorySize := 6
reader := strings.NewReader(input)
estimatedUniqueWords := EstimateUniqueWordsIter(reader, memorySize)
if estimatedUniqueWords != expectedUniqueWords {
// ...
}
f()
}

View File

@@ -0,0 +1,18 @@
// compile -d=libfuzzer
// Copyright 2024 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
type T struct {
A
}
type A struct {
}
//go:noinline
func (a *A) Foo(s [2]string) {
}

View File

@@ -0,0 +1,23 @@
// run
// Copyright 2024 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 (
"reflect"
)
func main() {
pi := new(interface{})
v := reflect.ValueOf(pi).Elem()
if v.Kind() != reflect.Interface {
panic(0)
}
if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() {
return
}
panic(1)
}

View File

@@ -0,0 +1,17 @@
// compile
// Copyright 2024 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
func f() {
_:
_:
}
func main() {
f()
}

View File

@@ -0,0 +1,38 @@
// run -goexperiment noswissmap
// Copyright 2024 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
func nan() float64 {
var x, y float64
return x / y
}
func main() {
m := map[float64]int{}
// Make a small map with nan keys
for i := 0; i < 8; i++ {
m[nan()] = i
}
// Start iterating on it.
start := true
for _, v := range m {
if start {
// Add some more elements.
for i := 0; i < 10; i++ {
m[float64(i)] = i
}
// Now clear the map.
clear(m)
start = false
} else {
// We should never reach here.
panic(v)
}
}
}

View File

@@ -0,0 +1,20 @@
// run
// Copyright 2024 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
const maxUint64 = (1 << 64) - 1
//go:noinline
func f(n uint64) uint64 {
return maxUint64 - maxUint64%n
}
func main() {
for i := uint64(1); i < 20; i++ {
println(i, maxUint64-f(i))
}
}

View File

@@ -0,0 +1,19 @@
1 0
2 1
3 0
4 3
5 0
6 3
7 1
8 7
9 6
10 5
11 4
12 3
13 2
14 1
15 0
16 15
17 0
18 15
19 16

View File

@@ -4,12 +4,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test type-checking errors for go:notinheap.
// Test type-checking errors for not-in-heap types.
//go:build cgo
package p
//go:notinheap
type nih struct{}
import "runtime/cgo"
type nih struct{ _ cgo.Incomplete }
type embed4 map[nih]int // ERROR "incomplete \(or unallocatable\) map key not allowed"
@@ -27,25 +30,8 @@ type okay4 interface {
f(x nih) nih
}
// Type conversions don't let you sneak past notinheap.
type t1 struct{ x int }
//go:notinheap
type t2 t1
//go:notinheap
type t3 byte
//go:notinheap
type t4 rune
var sink interface{}
func i() {
sink = new(t1) // no error
sink = (*t2)(new(t1)) // ERROR "cannot convert(.|\n)*t2 is incomplete \(or unallocatable\)"
sink = (*t2)(new(struct{ x int })) // ERROR "cannot convert(.|\n)*t2 is incomplete \(or unallocatable\)"
sink = []t3("foo") // ERROR "cannot convert(.|\n)*t3 is incomplete \(or unallocatable\)"
sink = []t4("bar") // ERROR "cannot convert(.|\n)*t4 is incomplete \(or unallocatable\)"
func f() {
type embed7 map[nih]int // ERROR "incomplete \(or unallocatable\) map key not allowed"
type embed8 map[int]nih // ERROR "incomplete \(or unallocatable\) map value not allowed"
type emebd9 chan nih // ERROR "chan of incomplete \(or unallocatable\) type not allowed"
}