Update to go1.24.0
This commit is contained in:
@@ -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
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
79
test/fixedbugs/issue16241.go
Normal file
79
test/fixedbugs/issue16241.go
Normal 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)
|
||||
}
|
||||
60
test/fixedbugs/issue16241_64.go
Normal file
60
test/fixedbugs/issue16241_64.go
Normal 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)
|
||||
}
|
||||
13
test/fixedbugs/issue20027.go
Normal file
13
test/fixedbugs/issue20027.go
Normal 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"
|
||||
19
test/fixedbugs/issue24755.go
Normal file
19
test/fixedbugs/issue24755.go
Normal 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() {
|
||||
}
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
27
test/fixedbugs/issue67329.go
Normal file
27
test/fixedbugs/issue67329.go
Normal 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 ""
|
||||
}
|
||||
}
|
||||
12
test/fixedbugs/issue68292.go
Normal file
12
test/fixedbugs/issue68292.go
Normal 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\)"
|
||||
}
|
||||
16
test/fixedbugs/issue68526.dir/a/a.go
Normal file
16
test/fixedbugs/issue68526.dir/a/a.go
Normal 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]{}
|
||||
}
|
||||
45
test/fixedbugs/issue68526.dir/main.go
Normal file
45
test/fixedbugs/issue68526.dir/main.go
Normal 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)
|
||||
}
|
||||
}
|
||||
7
test/fixedbugs/issue68526.go
Normal file
7
test/fixedbugs/issue68526.go
Normal 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
|
||||
17
test/fixedbugs/issue68734.go
Normal file
17
test/fixedbugs/issue68734.go
Normal 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")
|
||||
}
|
||||
19
test/fixedbugs/issue68809.go
Normal file
19
test/fixedbugs/issue68809.go
Normal 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")
|
||||
}
|
||||
}
|
||||
41
test/fixedbugs/issue68816.go
Normal file
41
test/fixedbugs/issue68816.go
Normal 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()
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
18
test/fixedbugs/issue69825.go
Normal file
18
test/fixedbugs/issue69825.go
Normal 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) {
|
||||
}
|
||||
23
test/fixedbugs/issue70156.go
Normal file
23
test/fixedbugs/issue70156.go
Normal 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)
|
||||
}
|
||||
17
test/fixedbugs/issue70175.go
Normal file
17
test/fixedbugs/issue70175.go
Normal 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()
|
||||
}
|
||||
38
test/fixedbugs/issue70189.go
Normal file
38
test/fixedbugs/issue70189.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
20
test/fixedbugs/issue70481.go
Normal file
20
test/fixedbugs/issue70481.go
Normal 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))
|
||||
}
|
||||
}
|
||||
19
test/fixedbugs/issue70481.out
Normal file
19
test/fixedbugs/issue70481.out
Normal 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
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user