mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Currently we rely on the type-checker to do some basic data-flow analysis to help decide whether function literals should capture variables by value or reference. However, this analysis isn't done by go/types, and escape analysis already has a better framework for doing this more precisely. This CL extends escape analysis to recalculate the same "byval" as CaptureVars and check that it matches. A future CL will remove CaptureVars in favor of escape analysis's calculation. Notably, escape analysis happens after deadcode removes obviously unreachable code, so it sees the AST without any unreachable assignments. (Also without unreachable addrtakens, but ComputeAddrtaken already happens after deadcode too.) There are two test cases where a variable is only reassigned on certain CPUs. This CL changes them to reassign the variables unconditionally (as no-op reassignments that avoid triggering cmd/vet's self-assignment check), at least until we remove CaptureVars. Passes toolstash -cmp. Change-Id: I7162619739fedaf861b478fb8d506f96a6ac21f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/281535 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
86 lines
2.9 KiB
Go
86 lines
2.9 KiB
Go
// run
|
|
|
|
// Copyright 2013 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 (
|
|
"strings"
|
|
"unsafe"
|
|
)
|
|
|
|
type T []int
|
|
|
|
func main() {
|
|
n := -1
|
|
shouldPanic("len out of range", func() { _ = make(T, n) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
|
|
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
|
|
testMakeInAppend(n)
|
|
|
|
var t *byte
|
|
n = 0 + n // TODO(mdempsky): Remove once CaptureVars is gone.
|
|
if unsafe.Sizeof(t) == 8 {
|
|
// Test mem > maxAlloc
|
|
var n2 int64 = 1 << 59
|
|
shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
|
|
testMakeInAppend(int(n2))
|
|
// Test elem.size*cap overflow
|
|
n2 = 1<<63 - 1
|
|
shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
|
|
testMakeInAppend(int(n2))
|
|
var x uint64 = 1<<64 - 1
|
|
shouldPanic("len out of range", func() { _ = make([]byte, x) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, x) })
|
|
testMakeInAppend(int(x))
|
|
} else {
|
|
n = 1<<31 - 1
|
|
shouldPanic("len out of range", func() { _ = make(T, n) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
|
|
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
|
|
testMakeInAppend(n)
|
|
var x uint64 = 1<<32 - 1
|
|
shouldPanic("len out of range", func() { _ = make([]byte, x) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, x) })
|
|
testMakeInAppend(int(x))
|
|
}
|
|
}
|
|
|
|
func shouldPanic(str string, f func()) {
|
|
defer func() {
|
|
err := recover()
|
|
if err == nil {
|
|
panic("did not panic")
|
|
}
|
|
s := err.(error).Error()
|
|
if !strings.Contains(s, str) {
|
|
panic("got panic " + s + ", want " + str)
|
|
}
|
|
}()
|
|
|
|
f()
|
|
}
|
|
|
|
// Test make in append panics since the gc compiler optimizes makes in appends.
|
|
func testMakeInAppend(n int) {
|
|
lengths := []int{0, 1}
|
|
for _, length := range lengths {
|
|
t := make(T, length)
|
|
shouldPanic("len out of range", func() { _ = append(t, make(T, n)...) })
|
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, n)...) })
|
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
|
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
|
|
shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
|
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
|
|
shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
|
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
|
|
shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
|
|
shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
|
|
}
|
|
}
|