mirror of
https://github.com/golang/go
synced 2024-09-05 07:54:46 +00:00
![Matthew Dempsky](/assets/img/avatar_default.png)
The conversion T(x) is implemented as *(*T)(x). Accordingly, runtime panic messages for (*T)(x) are made more general. Fixes #46505. Change-Id: I76317c0878b6a5908299506d392eed50d7ef6523 Reviewed-on: https://go-review.googlesource.com/c/go/+/430415 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Jenny Rakoczy <jenny@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org>
182 lines
3.9 KiB
Go
182 lines
3.9 KiB
Go
// errorcheck -0 -m -l
|
|
|
|
// Copyright 2015 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.
|
|
|
|
// Test escape analysis for slices.
|
|
|
|
package escape
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var sink interface{}
|
|
|
|
func slice0() {
|
|
var s []*int
|
|
// BAD: i should not escape
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s = append(s, &i)
|
|
_ = s
|
|
}
|
|
|
|
func slice1() *int {
|
|
var s []*int
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s = append(s, &i)
|
|
return s[0]
|
|
}
|
|
|
|
func slice2() []*int {
|
|
var s []*int
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s = append(s, &i)
|
|
return s
|
|
}
|
|
|
|
func slice3() *int {
|
|
var s []*int
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s = append(s, &i)
|
|
for _, p := range s {
|
|
return p
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func slice4(s []*int) { // ERROR "s does not escape"
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s[0] = &i
|
|
}
|
|
|
|
func slice5(s []*int) { // ERROR "s does not escape"
|
|
if s != nil {
|
|
s = make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
|
|
}
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s[0] = &i
|
|
}
|
|
|
|
func slice6() {
|
|
s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
|
|
// BAD: i should not escape
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s[0] = &i
|
|
_ = s
|
|
}
|
|
|
|
func slice7() *int {
|
|
s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s[0] = &i
|
|
return s[0]
|
|
}
|
|
|
|
func slice8() {
|
|
i := 0
|
|
s := []*int{&i} // ERROR "\[\]\*int{...} does not escape"
|
|
_ = s
|
|
}
|
|
|
|
func slice9() *int {
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s := []*int{&i} // ERROR "\[\]\*int{...} does not escape"
|
|
return s[0]
|
|
}
|
|
|
|
func slice10() []*int {
|
|
i := 0 // ERROR "moved to heap: i"
|
|
s := []*int{&i} // ERROR "\[\]\*int{...} escapes to heap"
|
|
return s
|
|
}
|
|
|
|
func slice11() {
|
|
i := 2
|
|
s := make([]int, 2, 3) // ERROR "make\(\[\]int, 2, 3\) does not escape"
|
|
s = make([]int, i, 3) // ERROR "make\(\[\]int, i, 3\) does not escape"
|
|
s = make([]int, i, 1) // ERROR "make\(\[\]int, i, 1\) does not escape"
|
|
_ = s
|
|
}
|
|
|
|
func slice12(x []int) *[1]int { // ERROR "leaking param: x to result ~r0 level=0$"
|
|
return (*[1]int)(x)
|
|
}
|
|
|
|
func slice13(x []*int) [1]*int { // ERROR "leaking param: x to result ~r0 level=1$"
|
|
return [1]*int(x)
|
|
}
|
|
|
|
func envForDir(dir string) []string { // ERROR "dir does not escape"
|
|
env := os.Environ()
|
|
return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string{...} does not escape"
|
|
}
|
|
|
|
func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r0 level=0"
|
|
NextVar:
|
|
for _, inkv := range in {
|
|
k := strings.SplitAfterN(inkv, "=", 2)[0]
|
|
for i, outkv := range out {
|
|
if strings.HasPrefix(outkv, k) {
|
|
out[i] = inkv
|
|
continue NextVar
|
|
}
|
|
}
|
|
out = append(out, inkv)
|
|
}
|
|
return out
|
|
}
|
|
|
|
const (
|
|
IPv4len = 4
|
|
IPv6len = 16
|
|
)
|
|
|
|
var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
|
|
|
|
func IPv4(a, b, c, d byte) IP {
|
|
p := make(IP, IPv6len) // ERROR "make\(IP, IPv6len\) escapes to heap"
|
|
copy(p, v4InV6Prefix)
|
|
p[12] = a
|
|
p[13] = b
|
|
p[14] = c
|
|
p[15] = d
|
|
return p
|
|
}
|
|
|
|
type IP []byte
|
|
|
|
type IPAddr struct {
|
|
IP IP
|
|
Zone string // IPv6 scoped addressing zone
|
|
}
|
|
|
|
type resolveIPAddrTest struct {
|
|
network string
|
|
litAddrOrName string
|
|
addr *IPAddr
|
|
err error
|
|
}
|
|
|
|
var resolveIPAddrTests = []resolveIPAddrTest{
|
|
{"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
|
|
{"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
|
|
{"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
|
|
}
|
|
|
|
func setupTestData() {
|
|
resolveIPAddrTests = append(resolveIPAddrTests,
|
|
[]resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest{...} does not escape"
|
|
{"ip",
|
|
"localhost",
|
|
&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
|
|
nil},
|
|
{"ip4",
|
|
"localhost",
|
|
&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
|
|
nil},
|
|
}...)
|
|
}
|