mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: use clearer error message for stuct literal
This CL changes "T literal.M" error message to "T{...}.M". It's clearer expression and focusing user on actual issue. Updates #38745 Change-Id: I84b455a86742f37e0bde5bf390aa02984eecc3c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/253677 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
d7384f3612
commit
2c95e3a6a8
@ -1407,7 +1407,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Right != nil {
|
if n.Right != nil {
|
||||||
mode.Fprintf(s, "%v literal", n.Right)
|
mode.Fprintf(s, "%v{%s}", n.Right, ellipsisIf(n.List.Len() != 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1421,7 +1421,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
|
|||||||
|
|
||||||
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
|
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
|
||||||
if mode == FErr {
|
if mode == FErr {
|
||||||
mode.Fprintf(s, "%v literal", n.Type)
|
mode.Fprintf(s, "%v{%s}", n.Type, ellipsisIf(n.List.Len() != 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List)
|
mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List)
|
||||||
@ -1934,3 +1934,10 @@ func indent(s fmt.State) {
|
|||||||
fmt.Fprint(s, ". ")
|
fmt.Fprint(s, ". ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ellipsisIf(b bool) string {
|
||||||
|
if b {
|
||||||
|
return "..."
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -46,8 +46,8 @@ var _ A0 = T0{}
|
|||||||
var _ T0 = A0{}
|
var _ T0 = A0{}
|
||||||
|
|
||||||
// But aliases and original types cannot be used with new types based on them.
|
// But aliases and original types cannot be used with new types based on them.
|
||||||
var _ N0 = T0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
var _ N0 = T0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
|
||||||
var _ N0 = A0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
var _ N0 = A0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
|
||||||
|
|
||||||
var _ A5 = Value{}
|
var _ A5 = Value{}
|
||||||
|
|
||||||
@ -82,10 +82,10 @@ func _() {
|
|||||||
var _ A0 = T0{}
|
var _ A0 = T0{}
|
||||||
var _ T0 = A0{}
|
var _ T0 = A0{}
|
||||||
|
|
||||||
var _ N0 = T0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
var _ N0 = T0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
|
||||||
var _ N0 = A0{} // ERROR "cannot use T0 literal \(type T0\) as type N0 in assignment|incompatible type"
|
var _ N0 = A0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
|
||||||
|
|
||||||
var _ A5 = Value{} // ERROR "cannot use reflect\.Value literal \(type reflect.Value\) as type A5 in assignment|incompatible type"
|
var _ A5 = Value{} // ERROR "cannot use reflect\.Value{} \(type reflect.Value\) as type A5 in assignment|incompatible type"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalid type alias declarations.
|
// Invalid type alias declarations.
|
||||||
|
@ -19,7 +19,7 @@ var (
|
|||||||
_ = sum(1.0, 2.0)
|
_ = sum(1.0, 2.0)
|
||||||
_ = sum(1.5) // ERROR "integer"
|
_ = sum(1.5) // ERROR "integer"
|
||||||
_ = sum("hello") // ERROR ".hello. .type untyped string. as type int|incompatible"
|
_ = sum("hello") // ERROR ".hello. .type untyped string. as type int|incompatible"
|
||||||
_ = sum([]int{1}) // ERROR "\[\]int literal.*as type int|incompatible"
|
_ = sum([]int{1}) // ERROR "\[\]int{...}.*as type int|incompatible"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sum3(int, int, int) int { return 0 }
|
func sum3(int, int, int) int { return 0 }
|
||||||
|
@ -118,15 +118,15 @@ type Bar struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewBar() *Bar {
|
func NewBar() *Bar {
|
||||||
return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$"
|
return &Bar{42, nil} // ERROR "&Bar{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
|
func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
|
||||||
return &Bar{42, x} // ERROR "&Bar literal escapes to heap$"
|
return &Bar{42, x} // ERROR "&Bar{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
|
func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
|
||||||
return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$"
|
return &Bar{*x, nil} // ERROR "&Bar{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
|
func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
|
||||||
@ -173,7 +173,7 @@ type Bar2 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewBar2() *Bar2 {
|
func NewBar2() *Bar2 {
|
||||||
return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$"
|
return &Bar2{[12]int{42}, nil} // ERROR "&Bar2{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
|
func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
|
||||||
@ -539,7 +539,7 @@ func foo72b() [10]*int {
|
|||||||
|
|
||||||
// issue 2145
|
// issue 2145
|
||||||
func foo73() {
|
func foo73() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v
|
vv := v
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -550,7 +550,7 @@ func foo73() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo731() {
|
func foo731() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v // ERROR "moved to heap: vv$"
|
vv := v // ERROR "moved to heap: vv$"
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -562,7 +562,7 @@ func foo731() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo74() {
|
func foo74() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v
|
vv := v
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -574,7 +574,7 @@ func foo74() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo74a() {
|
func foo74a() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v // ERROR "moved to heap: vv$"
|
vv := v // ERROR "moved to heap: vv$"
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -589,7 +589,7 @@ func foo74a() {
|
|||||||
// issue 3975
|
// issue 3975
|
||||||
func foo74b() {
|
func foo74b() {
|
||||||
var array [3]func()
|
var array [3]func()
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for i, v := range s {
|
for i, v := range s {
|
||||||
vv := v
|
vv := v
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -601,7 +601,7 @@ func foo74b() {
|
|||||||
|
|
||||||
func foo74c() {
|
func foo74c() {
|
||||||
var array [3]func()
|
var array [3]func()
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for i, v := range s {
|
for i, v := range s {
|
||||||
vv := v // ERROR "moved to heap: vv$"
|
vv := v // ERROR "moved to heap: vv$"
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -759,15 +759,15 @@ type LimitedFooer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
|
func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
|
||||||
return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$"
|
return &LimitedFooer{r, n} // ERROR "&LimitedFooer{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
|
func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
|
||||||
@ -870,15 +870,15 @@ func foo106(x *int) { // ERROR "leaking param: x$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo109(x *int) *int { // ERROR "leaking param: x$"
|
func foo109(x *int) *int { // ERROR "leaking param: x$"
|
||||||
m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal does not escape$"
|
m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} does not escape$"
|
||||||
for k, _ := range m {
|
for k, _ := range m {
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
@ -886,12 +886,12 @@ func foo109(x *int) *int { // ERROR "leaking param: x$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo110(x *int) *int { // ERROR "leaking param: x$"
|
func foo110(x *int) *int { // ERROR "leaking param: x$"
|
||||||
m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal does not escape$"
|
m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} does not escape$"
|
||||||
return m[nil]
|
return m[nil]
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
|
func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
|
||||||
m := []*int{x} // ERROR "\[\]\*int literal does not escape$"
|
m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
|
||||||
return m[0]
|
return m[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,7 +906,7 @@ func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
|
func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
|
||||||
m := &Bar{ii: x} // ERROR "&Bar literal does not escape$"
|
m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
|
||||||
return m.ii
|
return m.ii
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1343,8 +1343,8 @@ func foo140() interface{} {
|
|||||||
X string
|
X string
|
||||||
T *T
|
T *T
|
||||||
}
|
}
|
||||||
t := &T{} // ERROR "&T literal escapes to heap$"
|
t := &T{} // ERROR "&T{} escapes to heap$"
|
||||||
return U{ // ERROR "U literal escapes to heap$"
|
return U{ // ERROR "U{...} escapes to heap$"
|
||||||
X: t.X,
|
X: t.X,
|
||||||
T: t,
|
T: t,
|
||||||
}
|
}
|
||||||
@ -1530,7 +1530,7 @@ type V struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewV(u U) *V { // ERROR "leaking param: u$"
|
func NewV(u U) *V { // ERROR "leaking param: u$"
|
||||||
return &V{u.String()} // ERROR "&V literal escapes to heap$"
|
return &V{u.String()} // ERROR "&V{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo152() {
|
func foo152() {
|
||||||
@ -1571,21 +1571,21 @@ type Lit struct {
|
|||||||
func ptrlitNoescape() {
|
func ptrlitNoescape() {
|
||||||
// Both literal and element do not escape.
|
// Both literal and element do not escape.
|
||||||
i := 0
|
i := 0
|
||||||
x := &Lit{&i} // ERROR "&Lit literal does not escape$"
|
x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
|
||||||
_ = x
|
_ = x
|
||||||
}
|
}
|
||||||
|
|
||||||
func ptrlitNoEscape2() {
|
func ptrlitNoEscape2() {
|
||||||
// Literal does not escape, but element does.
|
// Literal does not escape, but element does.
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
x := &Lit{&i} // ERROR "&Lit literal does not escape$"
|
x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
|
||||||
sink = *x
|
sink = *x
|
||||||
}
|
}
|
||||||
|
|
||||||
func ptrlitEscape() {
|
func ptrlitEscape() {
|
||||||
// Both literal and element escape.
|
// Both literal and element escape.
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
|
x := &Lit{&i} // ERROR "&Lit{...} escapes to heap$"
|
||||||
sink = x
|
sink = x
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1760,18 +1760,18 @@ func stringtoslicerune2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func slicerunetostring0() {
|
func slicerunetostring0() {
|
||||||
r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape$"
|
r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
|
||||||
s := string(r) // ERROR "string\(r\) does not escape$"
|
s := string(r) // ERROR "string\(r\) does not escape$"
|
||||||
_ = s
|
_ = s
|
||||||
}
|
}
|
||||||
|
|
||||||
func slicerunetostring1() string {
|
func slicerunetostring1() string {
|
||||||
r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape$"
|
r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
|
||||||
return string(r) // ERROR "string\(r\) escapes to heap$"
|
return string(r) // ERROR "string\(r\) escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func slicerunetostring2() {
|
func slicerunetostring2() {
|
||||||
r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape$"
|
r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
|
||||||
sink = string(r) // ERROR "string\(r\) escapes to heap$"
|
sink = string(r) // ERROR "string\(r\) escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,15 +118,15 @@ type Bar struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewBar() *Bar {
|
func NewBar() *Bar {
|
||||||
return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$"
|
return &Bar{42, nil} // ERROR "&Bar{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
|
func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
|
||||||
return &Bar{42, x} // ERROR "&Bar literal escapes to heap$"
|
return &Bar{42, x} // ERROR "&Bar{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
|
func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
|
||||||
return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$"
|
return &Bar{*x, nil} // ERROR "&Bar{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
|
func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
|
||||||
@ -173,7 +173,7 @@ type Bar2 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewBar2() *Bar2 {
|
func NewBar2() *Bar2 {
|
||||||
return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$"
|
return &Bar2{[12]int{42}, nil} // ERROR "&Bar2{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
|
func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
|
||||||
@ -539,7 +539,7 @@ func foo72b() [10]*int {
|
|||||||
|
|
||||||
// issue 2145
|
// issue 2145
|
||||||
func foo73() {
|
func foo73() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v
|
vv := v
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -550,7 +550,7 @@ func foo73() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo731() {
|
func foo731() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v // ERROR "moved to heap: vv$"
|
vv := v // ERROR "moved to heap: vv$"
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -562,7 +562,7 @@ func foo731() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo74() {
|
func foo74() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v
|
vv := v
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -574,7 +574,7 @@ func foo74() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo74a() {
|
func foo74a() {
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for _, v := range s {
|
for _, v := range s {
|
||||||
vv := v // ERROR "moved to heap: vv$"
|
vv := v // ERROR "moved to heap: vv$"
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -589,7 +589,7 @@ func foo74a() {
|
|||||||
// issue 3975
|
// issue 3975
|
||||||
func foo74b() {
|
func foo74b() {
|
||||||
var array [3]func()
|
var array [3]func()
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for i, v := range s {
|
for i, v := range s {
|
||||||
vv := v
|
vv := v
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -601,7 +601,7 @@ func foo74b() {
|
|||||||
|
|
||||||
func foo74c() {
|
func foo74c() {
|
||||||
var array [3]func()
|
var array [3]func()
|
||||||
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape$"
|
s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
|
||||||
for i, v := range s {
|
for i, v := range s {
|
||||||
vv := v // ERROR "moved to heap: vv$"
|
vv := v // ERROR "moved to heap: vv$"
|
||||||
// actually just escapes its scope
|
// actually just escapes its scope
|
||||||
@ -759,15 +759,15 @@ type LimitedFooer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
|
func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
|
||||||
return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$"
|
return &LimitedFooer{r, n} // ERROR "&LimitedFooer{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
|
func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
|
||||||
@ -870,15 +870,15 @@ func foo106(x *int) { // ERROR "leaking param: x$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
|
||||||
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
|
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo109(x *int) *int { // ERROR "leaking param: x$"
|
func foo109(x *int) *int { // ERROR "leaking param: x$"
|
||||||
m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal does not escape$"
|
m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} does not escape$"
|
||||||
for k, _ := range m {
|
for k, _ := range m {
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
@ -886,12 +886,12 @@ func foo109(x *int) *int { // ERROR "leaking param: x$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo110(x *int) *int { // ERROR "leaking param: x$"
|
func foo110(x *int) *int { // ERROR "leaking param: x$"
|
||||||
m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal does not escape$"
|
m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} does not escape$"
|
||||||
return m[nil]
|
return m[nil]
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
|
func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
|
||||||
m := []*int{x} // ERROR "\[\]\*int literal does not escape$"
|
m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
|
||||||
return m[0]
|
return m[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,7 +906,7 @@ func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
|
func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
|
||||||
m := &Bar{ii: x} // ERROR "&Bar literal does not escape$"
|
m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
|
||||||
return m.ii
|
return m.ii
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1343,8 +1343,8 @@ func foo140() interface{} {
|
|||||||
X string
|
X string
|
||||||
T *T
|
T *T
|
||||||
}
|
}
|
||||||
t := &T{} // ERROR "&T literal escapes to heap$"
|
t := &T{} // ERROR "&T{} escapes to heap$"
|
||||||
return U{ // ERROR "U literal escapes to heap$"
|
return U{ // ERROR "U{...} escapes to heap$"
|
||||||
X: t.X,
|
X: t.X,
|
||||||
T: t,
|
T: t,
|
||||||
}
|
}
|
||||||
@ -1530,7 +1530,7 @@ type V struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewV(u U) *V { // ERROR "leaking param: u$"
|
func NewV(u U) *V { // ERROR "leaking param: u$"
|
||||||
return &V{u.String()} // ERROR "&V literal escapes to heap$"
|
return &V{u.String()} // ERROR "&V{...} escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo152() {
|
func foo152() {
|
||||||
@ -1571,21 +1571,21 @@ type Lit struct {
|
|||||||
func ptrlitNoescape() {
|
func ptrlitNoescape() {
|
||||||
// Both literal and element do not escape.
|
// Both literal and element do not escape.
|
||||||
i := 0
|
i := 0
|
||||||
x := &Lit{&i} // ERROR "&Lit literal does not escape$"
|
x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
|
||||||
_ = x
|
_ = x
|
||||||
}
|
}
|
||||||
|
|
||||||
func ptrlitNoEscape2() {
|
func ptrlitNoEscape2() {
|
||||||
// Literal does not escape, but element does.
|
// Literal does not escape, but element does.
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
x := &Lit{&i} // ERROR "&Lit literal does not escape$"
|
x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
|
||||||
sink = *x
|
sink = *x
|
||||||
}
|
}
|
||||||
|
|
||||||
func ptrlitEscape() {
|
func ptrlitEscape() {
|
||||||
// Both literal and element escape.
|
// Both literal and element escape.
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
|
x := &Lit{&i} // ERROR "&Lit{...} escapes to heap$"
|
||||||
sink = x
|
sink = x
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1760,18 +1760,18 @@ func stringtoslicerune2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func slicerunetostring0() {
|
func slicerunetostring0() {
|
||||||
r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape$"
|
r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
|
||||||
s := string(r) // ERROR "string\(r\) does not escape$"
|
s := string(r) // ERROR "string\(r\) does not escape$"
|
||||||
_ = s
|
_ = s
|
||||||
}
|
}
|
||||||
|
|
||||||
func slicerunetostring1() string {
|
func slicerunetostring1() string {
|
||||||
r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape$"
|
r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
|
||||||
return string(r) // ERROR "string\(r\) escapes to heap$"
|
return string(r) // ERROR "string\(r\) escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func slicerunetostring2() {
|
func slicerunetostring2() {
|
||||||
r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape$"
|
r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
|
||||||
sink = string(r) // ERROR "string\(r\) escapes to heap$"
|
sink = string(r) // ERROR "string\(r\) escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,5 +50,5 @@ func bar() {
|
|||||||
f := prototype
|
f := prototype
|
||||||
f = func(ss []string) { got = append(got, ss) } // ERROR "leaking param: ss" "func literal does not escape"
|
f = func(ss []string) { got = append(got, ss) } // ERROR "leaking param: ss" "func literal does not escape"
|
||||||
s := "string"
|
s := "string"
|
||||||
f([]string{s}) // ERROR "\[\]string literal escapes to heap"
|
f([]string{s}) // ERROR "\[\]string{...} escapes to heap"
|
||||||
}
|
}
|
||||||
|
@ -127,20 +127,20 @@ func field12() {
|
|||||||
|
|
||||||
func field13() {
|
func field13() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
x := &X{p1: &i} // ERROR "&X literal does not escape$"
|
x := &X{p1: &i} // ERROR "&X{...} does not escape$"
|
||||||
sink = x.p1
|
sink = x.p1
|
||||||
}
|
}
|
||||||
|
|
||||||
func field14() {
|
func field14() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
// BAD: &i should not escape
|
// BAD: &i should not escape
|
||||||
x := &X{p1: &i} // ERROR "&X literal does not escape$"
|
x := &X{p1: &i} // ERROR "&X{...} does not escape$"
|
||||||
sink = x.p2
|
sink = x.p2
|
||||||
}
|
}
|
||||||
|
|
||||||
func field15() {
|
func field15() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
x := &X{p1: &i} // ERROR "&X literal escapes to heap$"
|
x := &X{p1: &i} // ERROR "&X{...} escapes to heap$"
|
||||||
sink = x
|
sink = x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ func efaceEscape0() {
|
|||||||
_ = x
|
_ = x
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M0{&i}
|
v := M0{&i}
|
||||||
var x M = v
|
var x M = v
|
||||||
sink = x
|
sink = x
|
||||||
@ -50,7 +50,7 @@ func efaceEscape0() {
|
|||||||
_ = v1
|
_ = v1
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M0{&i}
|
v := M0{&i}
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v
|
var x M = v
|
||||||
@ -58,14 +58,14 @@ func efaceEscape0() {
|
|||||||
sink = v1
|
sink = v1
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M0{&i}
|
v := M0{&i}
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v
|
var x M = v
|
||||||
x.M()
|
x.M()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M0{&i}
|
v := M0{&i}
|
||||||
var x M = v
|
var x M = v
|
||||||
mescapes(x)
|
mescapes(x)
|
||||||
@ -91,46 +91,46 @@ func efaceEscape1() {
|
|||||||
{
|
{
|
||||||
i := 0
|
i := 0
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
var x M = v // ERROR "v does not escape"
|
var x M = v // ERROR "v does not escape"
|
||||||
_ = x
|
_ = x
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
var x M = v // ERROR "v escapes to heap"
|
var x M = v // ERROR "v escapes to heap"
|
||||||
sink = x
|
sink = x
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0
|
i := 0
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
var x M = v // ERROR "v does not escape"
|
var x M = v // ERROR "v does not escape"
|
||||||
v1 := x.(M1)
|
v1 := x.(M1)
|
||||||
_ = v1
|
_ = v1
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
var x M = v // ERROR "v does not escape"
|
var x M = v // ERROR "v does not escape"
|
||||||
v1 := x.(M1)
|
v1 := x.(M1)
|
||||||
sink = v1 // ERROR "v1 escapes to heap"
|
sink = v1 // ERROR "v1 escapes to heap"
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v // ERROR "v escapes to heap"
|
var x M = v // ERROR "v escapes to heap"
|
||||||
x.M()
|
x.M()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
var x M = v // ERROR "v escapes to heap"
|
var x M = v // ERROR "v escapes to heap"
|
||||||
mescapes(x)
|
mescapes(x)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0
|
i := 0
|
||||||
v := M1{&i, 0}
|
v := M1{&i, 0}
|
||||||
var x M = v // ERROR "v does not escape"
|
var x M = v // ERROR "v does not escape"
|
||||||
mdoesnotescape(x)
|
mdoesnotescape(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,26 +146,26 @@ func (*M2) M() {
|
|||||||
func efaceEscape2() {
|
func efaceEscape2() {
|
||||||
{
|
{
|
||||||
i := 0
|
i := 0
|
||||||
v := &M2{&i} // ERROR "&M2 literal does not escape"
|
v := &M2{&i} // ERROR "&M2{...} does not escape"
|
||||||
var x M = v
|
var x M = v
|
||||||
_ = x
|
_ = x
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
|
v := &M2{&i} // ERROR "&M2{...} escapes to heap"
|
||||||
var x M = v
|
var x M = v
|
||||||
sink = x
|
sink = x
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0
|
i := 0
|
||||||
v := &M2{&i} // ERROR "&M2 literal does not escape"
|
v := &M2{&i} // ERROR "&M2{...} does not escape"
|
||||||
var x M = v
|
var x M = v
|
||||||
v1 := x.(*M2)
|
v1 := x.(*M2)
|
||||||
_ = v1
|
_ = v1
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
|
v := &M2{&i} // ERROR "&M2{...} escapes to heap"
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v
|
var x M = v
|
||||||
v1 := x.(*M2)
|
v1 := x.(*M2)
|
||||||
@ -173,7 +173,7 @@ func efaceEscape2() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := &M2{&i} // ERROR "&M2 literal does not escape"
|
v := &M2{&i} // ERROR "&M2{...} does not escape"
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v
|
var x M = v
|
||||||
v1 := x.(*M2)
|
v1 := x.(*M2)
|
||||||
@ -181,7 +181,7 @@ func efaceEscape2() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := &M2{&i} // ERROR "&M2 literal does not escape"
|
v := &M2{&i} // ERROR "&M2{...} does not escape"
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v
|
var x M = v
|
||||||
v1, ok := x.(*M2)
|
v1, ok := x.(*M2)
|
||||||
@ -190,20 +190,20 @@ func efaceEscape2() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
|
v := &M2{&i} // ERROR "&M2{...} escapes to heap"
|
||||||
// BAD: v does not escape to heap here
|
// BAD: v does not escape to heap here
|
||||||
var x M = v
|
var x M = v
|
||||||
x.M()
|
x.M()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
|
v := &M2{&i} // ERROR "&M2{...} escapes to heap"
|
||||||
var x M = v
|
var x M = v
|
||||||
mescapes(x)
|
mescapes(x)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
i := 0
|
i := 0
|
||||||
v := &M2{&i} // ERROR "&M2 literal does not escape"
|
v := &M2{&i} // ERROR "&M2{...} does not escape"
|
||||||
var x M = v
|
var x M = v
|
||||||
mdoesnotescape(x)
|
mdoesnotescape(x)
|
||||||
}
|
}
|
||||||
@ -219,8 +219,8 @@ type T2 struct {
|
|||||||
|
|
||||||
func dotTypeEscape() *T2 { // #11931
|
func dotTypeEscape() *T2 { // #11931
|
||||||
var x interface{}
|
var x interface{}
|
||||||
x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1 literal does not escape"
|
x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1{...} does not escape"
|
||||||
return &T2{ // ERROR "&T2 literal escapes to heap"
|
return &T2{ // ERROR "&T2{...} escapes to heap"
|
||||||
T1: *(x.(*T1)),
|
T1: *(x.(*T1)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ func dotTypeEscape2() { // #13805, #15796
|
|||||||
var x interface{} = i // ERROR "i does not escape"
|
var x interface{} = i // ERROR "i does not escape"
|
||||||
var y interface{} = j // ERROR "j does not escape"
|
var y interface{} = j // ERROR "j does not escape"
|
||||||
|
|
||||||
sink = x.(int) // ERROR "x.\(int\) escapes to heap"
|
sink = x.(int) // ERROR "x.\(int\) escapes to heap"
|
||||||
sink, *(&ok) = y.(int)
|
sink, *(&ok) = y.(int)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ type ConstPtr2 struct {
|
|||||||
|
|
||||||
func constptr0() {
|
func constptr0() {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
x := &ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
// BAD: i should not escape here
|
// BAD: i should not escape here
|
||||||
x.p = &i
|
x.p = &i
|
||||||
_ = x
|
_ = x
|
||||||
@ -31,55 +31,55 @@ func constptr0() {
|
|||||||
|
|
||||||
func constptr01() *ConstPtr {
|
func constptr01() *ConstPtr {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
|
x := &ConstPtr{} // ERROR "&ConstPtr{} escapes to heap"
|
||||||
x.p = &i
|
x.p = &i
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr02() ConstPtr {
|
func constptr02() ConstPtr {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
x := &ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
x.p = &i
|
x.p = &i
|
||||||
return *x
|
return *x
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr03() **ConstPtr {
|
func constptr03() **ConstPtr {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" "moved to heap: x"
|
x := &ConstPtr{} // ERROR "&ConstPtr{} escapes to heap" "moved to heap: x"
|
||||||
x.p = &i
|
x.p = &i
|
||||||
return &x
|
return &x
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr1() {
|
func constptr1() {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
|
x := &ConstPtr{} // ERROR "&ConstPtr{} escapes to heap"
|
||||||
x.p = &i
|
x.p = &i
|
||||||
sink = x
|
sink = x
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr2() {
|
func constptr2() {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
x := &ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
x.p = &i
|
x.p = &i
|
||||||
sink = *x // ERROR "\*x escapes to heap"
|
sink = *x // ERROR "\*x escapes to heap"
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr4() *ConstPtr {
|
func constptr4() *ConstPtr {
|
||||||
p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
|
p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
|
||||||
*p = *&ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
*p = *&ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr5() *ConstPtr {
|
func constptr5() *ConstPtr {
|
||||||
p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
|
p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
|
||||||
p1 := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
p1 := &ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
*p = *p1
|
*p = *p1
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: p should not escape here
|
// BAD: p should not escape here
|
||||||
func constptr6(p *ConstPtr) { // ERROR "leaking param content: p"
|
func constptr6(p *ConstPtr) { // ERROR "leaking param content: p"
|
||||||
p1 := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
p1 := &ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
*p1 = *p
|
*p1 = *p
|
||||||
_ = p1
|
_ = p1
|
||||||
}
|
}
|
||||||
@ -102,17 +102,17 @@ func constptr8() *ConstPtr {
|
|||||||
func constptr9() ConstPtr {
|
func constptr9() ConstPtr {
|
||||||
p := new(ConstPtr) // ERROR "new\(ConstPtr\) does not escape"
|
p := new(ConstPtr) // ERROR "new\(ConstPtr\) does not escape"
|
||||||
var p1 ConstPtr2
|
var p1 ConstPtr2
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
p1.p = &i
|
p1.p = &i
|
||||||
p.c = p1
|
p.c = p1
|
||||||
return *p
|
return *p
|
||||||
}
|
}
|
||||||
|
|
||||||
func constptr10() ConstPtr {
|
func constptr10() ConstPtr {
|
||||||
x := &ConstPtr{} // ERROR "moved to heap: x" "&ConstPtr literal escapes to heap"
|
x := &ConstPtr{} // ERROR "moved to heap: x" "&ConstPtr{} escapes to heap"
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
var p *ConstPtr
|
var p *ConstPtr
|
||||||
p = &ConstPtr{p: &i, x: &x} // ERROR "&ConstPtr literal does not escape"
|
p = &ConstPtr{p: &i, x: &x} // ERROR "&ConstPtr{...} does not escape"
|
||||||
var pp **ConstPtr
|
var pp **ConstPtr
|
||||||
pp = &p
|
pp = &p
|
||||||
return **pp
|
return **pp
|
||||||
@ -121,7 +121,7 @@ func constptr10() ConstPtr {
|
|||||||
func constptr11() *ConstPtr {
|
func constptr11() *ConstPtr {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
|
p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
|
||||||
p1 := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
|
p1 := &ConstPtr{} // ERROR "&ConstPtr{} does not escape"
|
||||||
p1.p = &i
|
p1.p = &i
|
||||||
*p = *p1
|
*p = *p1
|
||||||
return p
|
return p
|
||||||
@ -134,7 +134,7 @@ func foo(p **int) { // ERROR "p does not escape"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foo1(p *int) { // ERROR "p does not escape"
|
func foo1(p *int) { // ERROR "p does not escape"
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
y := &p
|
y := &p
|
||||||
*y = &i
|
*y = &i
|
||||||
}
|
}
|
||||||
@ -148,13 +148,13 @@ func foo2() {
|
|||||||
var z Z
|
var z Z
|
||||||
z.f = &x
|
z.f = &x
|
||||||
p := z.f
|
p := z.f
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
*p = &i
|
*p = &i
|
||||||
}
|
}
|
||||||
|
|
||||||
var global *byte
|
var global *byte
|
||||||
|
|
||||||
func f() {
|
func f() {
|
||||||
var x byte // ERROR "moved to heap: x"
|
var x byte // ERROR "moved to heap: x"
|
||||||
global = &*&x
|
global = &*&x
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ func map0() {
|
|||||||
// BAD: i should not escape
|
// BAD: i should not escape
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
// BAD: j should not escape
|
// BAD: j should not escape
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m[&i] = &j
|
m[&i] = &j
|
||||||
_ = m
|
_ = m
|
||||||
}
|
}
|
||||||
@ -23,8 +23,8 @@ func map0() {
|
|||||||
func map1() *int {
|
func map1() *int {
|
||||||
m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
||||||
// BAD: i should not escape
|
// BAD: i should not escape
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m[&i] = &j
|
m[&i] = &j
|
||||||
return m[&i]
|
return m[&i]
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ func map3() []*int {
|
|||||||
m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
// BAD: j should not escape
|
// BAD: j should not escape
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m[&i] = &j
|
m[&i] = &j
|
||||||
var r []*int
|
var r []*int
|
||||||
for k := range m {
|
for k := range m {
|
||||||
@ -53,8 +53,8 @@ func map3() []*int {
|
|||||||
func map4() []*int {
|
func map4() []*int {
|
||||||
m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
||||||
// BAD: i should not escape
|
// BAD: i should not escape
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m[&i] = &j
|
m[&i] = &j
|
||||||
var r []*int
|
var r []*int
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
@ -68,8 +68,8 @@ func map4() []*int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func map5(m map[*int]*int) { // ERROR "m does not escape"
|
func map5(m map[*int]*int) { // ERROR "m does not escape"
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m[&i] = &j
|
m[&i] = &j
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ func map6(m map[*int]*int) { // ERROR "m does not escape"
|
|||||||
if m != nil {
|
if m != nil {
|
||||||
m = make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
m = make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape"
|
||||||
}
|
}
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m[&i] = &j
|
m[&i] = &j
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,14 +87,14 @@ func map7() {
|
|||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
// BAD: j should not escape
|
// BAD: j should not escape
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m := map[*int]*int{&i: &j} // ERROR "literal does not escape"
|
m := map[*int]*int{&i: &j} // ERROR "map\[\*int\]\*int{...} does not escape"
|
||||||
_ = m
|
_ = m
|
||||||
}
|
}
|
||||||
|
|
||||||
func map8() {
|
func map8() {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m := map[*int]*int{&i: &j} // ERROR "literal escapes to heap"
|
m := map[*int]*int{&i: &j} // ERROR "map\[\*int\]\*int{...} escapes to heap"
|
||||||
sink = m
|
sink = m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +102,6 @@ func map9() *int {
|
|||||||
// BAD: i should not escape
|
// BAD: i should not escape
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
j := 0 // ERROR "moved to heap: j"
|
j := 0 // ERROR "moved to heap: j"
|
||||||
m := map[*int]*int{&i: &j} // ERROR "literal does not escape"
|
m := map[*int]*int{&i: &j} // ERROR "map\[\*int\]\*int{...} does not escape"
|
||||||
return m[nil]
|
return m[nil]
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ func caller0a() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller0b() {
|
func caller0b() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
sink = param0(&i)
|
sink = param0(&i)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,11 +150,11 @@ func caller3a() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller3b() {
|
func caller3b() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
j := 0 // ERROR "moved to heap: j$"
|
j := 0 // ERROR "moved to heap: j$"
|
||||||
p := Pair{&i, &j}
|
p := Pair{&i, &j}
|
||||||
param3(&p)
|
param3(&p)
|
||||||
sink = p // ERROR "p escapes to heap$"
|
sink = p // ERROR "p escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
// in -> rcvr
|
// in -> rcvr
|
||||||
@ -173,7 +173,7 @@ func caller4b() {
|
|||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := Pair{}
|
p := Pair{}
|
||||||
p.param4(&i)
|
p.param4(&i)
|
||||||
sink = p // ERROR "p escapes to heap$"
|
sink = p // ERROR "p escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
// in -> heap
|
// in -> heap
|
||||||
@ -182,7 +182,7 @@ func param5(i *int) { // ERROR "leaking param: i$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller5() {
|
func caller5() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
param5(&i)
|
param5(&i)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +192,8 @@ func param6(i ***int) { // ERROR "leaking param content: i$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller6a() {
|
func caller6a() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i // ERROR "moved to heap: p$"
|
p := &i // ERROR "moved to heap: p$"
|
||||||
p2 := &p
|
p2 := &p
|
||||||
param6(&p2)
|
param6(&p2)
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ func param7(i ***int) { // ERROR "leaking param content: i$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller7() {
|
func caller7() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i
|
p := &i
|
||||||
p2 := &p
|
p2 := &p
|
||||||
param7(&p2)
|
param7(&p2)
|
||||||
@ -234,8 +234,8 @@ func caller9a() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller9b() {
|
func caller9b() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i // ERROR "moved to heap: p$"
|
p := &i // ERROR "moved to heap: p$"
|
||||||
p2 := &p
|
p2 := &p
|
||||||
sink = param9(&p2)
|
sink = param9(&p2)
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ func caller10a() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller10b() {
|
func caller10b() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i
|
p := &i
|
||||||
p2 := &p
|
p2 := &p
|
||||||
sink = param10(&p2)
|
sink = param10(&p2)
|
||||||
@ -265,26 +265,26 @@ func param11(i **int) ***int { // ERROR "moved to heap: i$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller11a() {
|
func caller11a() {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
p := &i // ERROR "moved to heap: p"
|
p := &i // ERROR "moved to heap: p"
|
||||||
_ = param11(&p)
|
_ = param11(&p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func caller11b() {
|
func caller11b() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i // ERROR "moved to heap: p$"
|
p := &i // ERROR "moved to heap: p$"
|
||||||
sink = param11(&p)
|
sink = param11(&p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func caller11c() { // GOOD
|
func caller11c() { // GOOD
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i // ERROR "moved to heap: p"
|
p := &i // ERROR "moved to heap: p"
|
||||||
sink = *param11(&p)
|
sink = *param11(&p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func caller11d() {
|
func caller11d() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i // ERROR "moved to heap: p"
|
p := &i // ERROR "moved to heap: p"
|
||||||
p2 := &p
|
p2 := &p
|
||||||
sink = param11(p2)
|
sink = param11(p2)
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ func caller12a() {
|
|||||||
func caller12b() {
|
func caller12b() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
p := &i // ERROR "moved to heap: p$"
|
p := &i // ERROR "moved to heap: p$"
|
||||||
r := &Indir{} // ERROR "&Indir literal does not escape$"
|
r := &Indir{} // ERROR "&Indir{} does not escape$"
|
||||||
r.param12(&p)
|
r.param12(&p)
|
||||||
_ = r
|
_ = r
|
||||||
}
|
}
|
||||||
@ -359,7 +359,7 @@ func caller13b() {
|
|||||||
func caller13c() {
|
func caller13c() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
var p *int
|
var p *int
|
||||||
v := &Val{&p} // ERROR "&Val literal does not escape$"
|
v := &Val{&p} // ERROR "&Val{...} does not escape$"
|
||||||
v.param13(&i)
|
v.param13(&i)
|
||||||
_ = v
|
_ = v
|
||||||
}
|
}
|
||||||
@ -374,8 +374,8 @@ func caller13d() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func caller13e() {
|
func caller13e() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
var p *int // ERROR "moved to heap: p$"
|
var p *int // ERROR "moved to heap: p$"
|
||||||
v := Val{&p}
|
v := Val{&p}
|
||||||
v.param13(&i)
|
v.param13(&i)
|
||||||
sink = v
|
sink = v
|
||||||
@ -384,7 +384,7 @@ func caller13e() {
|
|||||||
func caller13f() {
|
func caller13f() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
var p *int // ERROR "moved to heap: p$"
|
var p *int // ERROR "moved to heap: p$"
|
||||||
v := &Val{&p} // ERROR "&Val literal escapes to heap$"
|
v := &Val{&p} // ERROR "&Val{...} escapes to heap$"
|
||||||
v.param13(&i)
|
v.param13(&i)
|
||||||
sink = v
|
sink = v
|
||||||
}
|
}
|
||||||
@ -400,9 +400,9 @@ func caller13g() {
|
|||||||
func caller13h() {
|
func caller13h() {
|
||||||
i := 0 // ERROR "moved to heap: i$"
|
i := 0 // ERROR "moved to heap: i$"
|
||||||
var p *int
|
var p *int
|
||||||
v := &Val{&p} // ERROR "&Val literal does not escape$"
|
v := &Val{&p} // ERROR "&Val{...} does not escape$"
|
||||||
v.param13(&i)
|
v.param13(&i)
|
||||||
sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
|
sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
|
||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
@ -412,15 +412,15 @@ type Node struct {
|
|||||||
var Sink *Node
|
var Sink *Node
|
||||||
|
|
||||||
func f(x *Node) { // ERROR "leaking param content: x"
|
func f(x *Node) { // ERROR "leaking param content: x"
|
||||||
Sink = &Node{x.p} // ERROR "&Node literal escapes to heap"
|
Sink = &Node{x.p} // ERROR "&Node{...} escapes to heap"
|
||||||
}
|
}
|
||||||
|
|
||||||
func g(x *Node) *Node { // ERROR "leaking param content: x"
|
func g(x *Node) *Node { // ERROR "leaking param content: x"
|
||||||
return &Node{x.p} // ERROR "&Node literal escapes to heap"
|
return &Node{x.p} // ERROR "&Node{...} escapes to heap"
|
||||||
}
|
}
|
||||||
|
|
||||||
func h(x *Node) { // ERROR "leaking param: x"
|
func h(x *Node) { // ERROR "leaking param: x"
|
||||||
y := &Node{x} // ERROR "&Node literal does not escape"
|
y := &Node{x} // ERROR "&Node{...} does not escape"
|
||||||
Sink = g(y)
|
Sink = g(y)
|
||||||
f(y)
|
f(y)
|
||||||
}
|
}
|
||||||
|
@ -77,19 +77,19 @@ func slice7() *int {
|
|||||||
|
|
||||||
func slice8() {
|
func slice8() {
|
||||||
i := 0
|
i := 0
|
||||||
s := []*int{&i} // ERROR "literal does not escape"
|
s := []*int{&i} // ERROR "\[\]\*int{...} does not escape"
|
||||||
_ = s
|
_ = s
|
||||||
}
|
}
|
||||||
|
|
||||||
func slice9() *int {
|
func slice9() *int {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
s := []*int{&i} // ERROR "literal does not escape"
|
s := []*int{&i} // ERROR "\[\]\*int{...} does not escape"
|
||||||
return s[0]
|
return s[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func slice10() []*int {
|
func slice10() []*int {
|
||||||
i := 0 // ERROR "moved to heap: i"
|
i := 0 // ERROR "moved to heap: i"
|
||||||
s := []*int{&i} // ERROR "literal escapes to heap"
|
s := []*int{&i} // ERROR "\[\]\*int{...} escapes to heap"
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ func slice11() {
|
|||||||
|
|
||||||
func envForDir(dir string) []string { // ERROR "dir does not escape"
|
func envForDir(dir string) []string { // ERROR "dir does not escape"
|
||||||
env := os.Environ()
|
env := os.Environ()
|
||||||
return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string literal does not escape"
|
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 ~r2 level=0"
|
func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r2 level=0"
|
||||||
@ -160,14 +160,14 @@ var resolveIPAddrTests = []resolveIPAddrTest{
|
|||||||
|
|
||||||
func setupTestData() {
|
func setupTestData() {
|
||||||
resolveIPAddrTests = append(resolveIPAddrTests,
|
resolveIPAddrTests = append(resolveIPAddrTests,
|
||||||
[]resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest literal does not escape"
|
[]resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest{...} does not escape"
|
||||||
{"ip",
|
{"ip",
|
||||||
"localhost",
|
"localhost",
|
||||||
&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap"
|
&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
|
||||||
nil},
|
nil},
|
||||||
{"ip4",
|
{"ip4",
|
||||||
"localhost",
|
"localhost",
|
||||||
&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap"
|
&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr{...} escapes to heap"
|
||||||
nil},
|
nil},
|
||||||
}...)
|
}...)
|
||||||
}
|
}
|
||||||
|
@ -35,27 +35,27 @@ func (u *U) SPPi() *string { // ERROR "leaking param: u to result ~r0 level=2$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tSPPi() {
|
func tSPPi() {
|
||||||
s := "cat" // ERROR "moved to heap: s$"
|
s := "cat" // ERROR "moved to heap: s$"
|
||||||
ps := &s
|
ps := &s
|
||||||
pps := &ps
|
pps := &ps
|
||||||
pu := &U{ps, pps} // ERROR "&U literal does not escape$"
|
pu := &U{ps, pps} // ERROR "&U{...} does not escape$"
|
||||||
Ssink = pu.SPPi()
|
Ssink = pu.SPPi()
|
||||||
}
|
}
|
||||||
|
|
||||||
func tiSPP() {
|
func tiSPP() {
|
||||||
s := "cat" // ERROR "moved to heap: s$"
|
s := "cat" // ERROR "moved to heap: s$"
|
||||||
ps := &s
|
ps := &s
|
||||||
pps := &ps
|
pps := &ps
|
||||||
pu := &U{ps, pps} // ERROR "&U literal does not escape$"
|
pu := &U{ps, pps} // ERROR "&U{...} does not escape$"
|
||||||
Ssink = *pu.SPP()
|
Ssink = *pu.SPP()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of ps
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of ps
|
||||||
func tSP() {
|
func tSP() {
|
||||||
s := "cat" // ERROR "moved to heap: s$"
|
s := "cat" // ERROR "moved to heap: s$"
|
||||||
ps := &s // ERROR "moved to heap: ps$"
|
ps := &s // ERROR "moved to heap: ps$"
|
||||||
pps := &ps
|
pps := &ps
|
||||||
pu := &U{ps, pps} // ERROR "&U literal does not escape$"
|
pu := &U{ps, pps} // ERROR "&U{...} does not escape$"
|
||||||
Ssink = pu.SP()
|
Ssink = pu.SP()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,72 +114,72 @@ func (v *V) UPiSPd() *string { // ERROR "leaking param: v to result ~r0 level=2$
|
|||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPa() {
|
func tUPiSPa() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPb() {
|
func tUPiSPb() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPc() {
|
func tUPiSPc() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPd() {
|
func tUPiSPd() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,16 +204,16 @@ func tUPiSPPia() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,16 +222,16 @@ func tUPiSPPib() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,16 +240,16 @@ func tUPiSPPic() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,16 +258,16 @@ func tUPiSPPid() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,13 +286,13 @@ func tUPPiSPPia() {
|
|||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog"
|
s4 := "dog"
|
||||||
s5 := "emu"
|
s5 := "emu"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6
|
ps6 := &s6
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes)
|
Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes)
|
||||||
}
|
}
|
||||||
|
@ -35,27 +35,27 @@ func (u U) SPPi() *string { // ERROR "leaking param: u to result ~r0 level=1$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tSPPi() {
|
func tSPPi() {
|
||||||
s := "cat" // ERROR "moved to heap: s$"
|
s := "cat" // ERROR "moved to heap: s$"
|
||||||
ps := &s
|
ps := &s
|
||||||
pps := &ps
|
pps := &ps
|
||||||
pu := &U{ps, pps} // ERROR "&U literal does not escape$"
|
pu := &U{ps, pps} // ERROR "&U{...} does not escape$"
|
||||||
Ssink = pu.SPPi()
|
Ssink = pu.SPPi()
|
||||||
}
|
}
|
||||||
|
|
||||||
func tiSPP() {
|
func tiSPP() {
|
||||||
s := "cat" // ERROR "moved to heap: s$"
|
s := "cat" // ERROR "moved to heap: s$"
|
||||||
ps := &s
|
ps := &s
|
||||||
pps := &ps
|
pps := &ps
|
||||||
pu := &U{ps, pps} // ERROR "&U literal does not escape$"
|
pu := &U{ps, pps} // ERROR "&U{...} does not escape$"
|
||||||
Ssink = *pu.SPP()
|
Ssink = *pu.SPP()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained analysis to avoid spurious escape of ps
|
// BAD: need fine-grained analysis to avoid spurious escape of ps
|
||||||
func tSP() {
|
func tSP() {
|
||||||
s := "cat" // ERROR "moved to heap: s$"
|
s := "cat" // ERROR "moved to heap: s$"
|
||||||
ps := &s // ERROR "moved to heap: ps$"
|
ps := &s // ERROR "moved to heap: ps$"
|
||||||
pps := &ps
|
pps := &ps
|
||||||
pu := &U{ps, pps} // ERROR "&U literal does not escape$"
|
pu := &U{ps, pps} // ERROR "&U{...} does not escape$"
|
||||||
Ssink = pu.SP()
|
Ssink = pu.SP()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,72 +114,72 @@ func (v V) UPiSPd() *string { // ERROR "leaking param: v to result ~r0 level=1$"
|
|||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPa() {
|
func tUPiSPa() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPa() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPb() {
|
func tUPiSPb() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPb() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPc() {
|
func tUPiSPc() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPc() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
// BAD: need fine-grained (field-sensitive) analysis to avoid spurious escape of all but &s3
|
||||||
func tUPiSPd() {
|
func tUPiSPd() {
|
||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat" // ERROR "moved to heap: s2$"
|
s2 := "bat" // ERROR "moved to heap: s2$"
|
||||||
s3 := "cat" // ERROR "moved to heap: s3$"
|
s3 := "cat" // ERROR "moved to heap: s3$"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
ps4 := &s4 // ERROR "moved to heap: ps4$"
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal escapes to heap$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} escapes to heap$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes)
|
Ssink = v.UPiSPd() // Ssink = &s3 (only &s3 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,16 +204,16 @@ func tUPiSPPia() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPia() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,16 +222,16 @@ func tUPiSPPib() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPib() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,16 +240,16 @@ func tUPiSPPic() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPic() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,16 +258,16 @@ func tUPiSPPid() {
|
|||||||
s1 := "ant"
|
s1 := "ant"
|
||||||
s2 := "bat"
|
s2 := "bat"
|
||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog" // ERROR "moved to heap: s4$"
|
s4 := "dog" // ERROR "moved to heap: s4$"
|
||||||
s5 := "emu" // ERROR "moved to heap: s5$"
|
s5 := "emu" // ERROR "moved to heap: s5$"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
ps6 := &s6 // ERROR "moved to heap: ps6$"
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
Ssink = v.UPiSPPid() // Ssink = *&ps4 = &s4 (only &s4 really escapes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,13 +286,13 @@ func tUPPiSPPia() { // This test is sensitive to the level cap in function summa
|
|||||||
s3 := "cat"
|
s3 := "cat"
|
||||||
s4 := "dog"
|
s4 := "dog"
|
||||||
s5 := "emu"
|
s5 := "emu"
|
||||||
s6 := "fox" // ERROR "moved to heap: s6$"
|
s6 := "fox" // ERROR "moved to heap: s6$"
|
||||||
ps2 := &s2
|
ps2 := &s2
|
||||||
ps4 := &s4
|
ps4 := &s4
|
||||||
ps6 := &s6
|
ps6 := &s6
|
||||||
u1 := U{&s1, &ps2}
|
u1 := U{&s1, &ps2}
|
||||||
u2 := &U{&s3, &ps4} // ERROR "&U literal does not escape$"
|
u2 := &U{&s3, &ps4} // ERROR "&U{...} does not escape$"
|
||||||
u3 := &U{&s5, &ps6} // ERROR "&U literal does not escape$"
|
u3 := &U{&s5, &ps6} // ERROR "&U{...} does not escape$"
|
||||||
v := &V{u1, u2, &u3} // ERROR "&V literal does not escape$"
|
v := &V{u1, u2, &u3} // ERROR "&V{...} does not escape$"
|
||||||
Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes)
|
Ssink = v.UPPiSPPia() // Ssink = *&ps6 = &s6 (only &s6 really escapes)
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ func TFooK2() {
|
|||||||
a := int32(1) // ERROR "moved to heap: a"
|
a := int32(1) // ERROR "moved to heap: a"
|
||||||
b := "cat"
|
b := "cat"
|
||||||
c := &a
|
c := &a
|
||||||
fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "&\[4\]interface {} literal does not escape"
|
fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "&\[4\]interface {}{...} does not escape"
|
||||||
isink = FooK(fs)
|
isink = FooK(fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +169,6 @@ func TFooL2() {
|
|||||||
a := int32(1) // ERROR "moved to heap: a"
|
a := int32(1) // ERROR "moved to heap: a"
|
||||||
b := "cat"
|
b := "cat"
|
||||||
c := &a
|
c := &a
|
||||||
s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "\[\]interface {} literal does not escape"
|
s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "\[\]interface {}{...} does not escape"
|
||||||
isink = FooL(s)
|
isink = FooL(s)
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ func test5(iter int) {
|
|||||||
var fn *str
|
var fn *str
|
||||||
for i := 0; i < maxI; i++ {
|
for i := 0; i < maxI; i++ {
|
||||||
// var fn *str // this makes it work, because fn stays off heap
|
// var fn *str // this makes it work, because fn stays off heap
|
||||||
fn = &str{m} // ERROR "&str literal escapes to heap"
|
fn = &str{m} // ERROR "&str{...} escapes to heap"
|
||||||
recur1(0, fn)
|
recur1(0, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ func test6(iter int) {
|
|||||||
// var fn *str
|
// var fn *str
|
||||||
for i := 0; i < maxI; i++ {
|
for i := 0; i < maxI; i++ {
|
||||||
var fn *str // this makes it work, because fn stays off heap
|
var fn *str // this makes it work, because fn stays off heap
|
||||||
fn = &str{m} // ERROR "&str literal does not escape"
|
fn = &str{m} // ERROR "&str{...} does not escape"
|
||||||
recur1(0, fn)
|
recur1(0, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,5 +12,5 @@ type Foo struct {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var s []int
|
var s []int
|
||||||
var _ string = append(s, Foo{""}) // ERROR "cannot use .. \(type untyped string\) as type int in field value" "cannot use Foo literal \(type Foo\) as type int in append" "cannot use append\(s\, Foo literal\) \(type \[\]int\) as type string in assignment"
|
var _ string = append(s, Foo{""}) // ERROR "cannot use .. \(type untyped string\) as type int in field value" "cannot use Foo{...} \(type Foo\) as type int in append" "cannot use append\(s\, Foo{...}\) \(type \[\]int\) as type string in assignment"
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ var N int
|
|||||||
func F1() {
|
func F1() {
|
||||||
var s S
|
var s S
|
||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
fs := []func(){ // ERROR "\[\]func\(\) literal does not escape"
|
fs := []func(){ // ERROR "\[\]func\(\){...} does not escape"
|
||||||
s.Inc, // ERROR "s.Inc does not escape"
|
s.Inc, // ERROR "s.Inc does not escape"
|
||||||
}
|
}
|
||||||
for _, f := range fs {
|
for _, f := range fs {
|
||||||
@ -28,7 +28,7 @@ func F1() {
|
|||||||
func F2() {
|
func F2() {
|
||||||
var s S
|
var s S
|
||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
for _, f := range []func(){ // ERROR "\[\]func\(\) literal does not escape"
|
for _, f := range []func(){ // ERROR "\[\]func\(\){...} does not escape"
|
||||||
s.Inc, // ERROR "s.Inc does not escape"
|
s.Inc, // ERROR "s.Inc does not escape"
|
||||||
} {
|
} {
|
||||||
f()
|
f()
|
||||||
|
@ -24,19 +24,19 @@ func main() {
|
|||||||
_ = Foo{
|
_ = Foo{
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
3, // ERROR "too few values in Foo literal"
|
3, // ERROR "too few values in Foo{...}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = Foo{
|
_ = Foo{
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
3,
|
3,
|
||||||
Bar{"A", "B"}, // ERROR "too many values in Bar literal"
|
Bar{"A", "B"}, // ERROR "too many values in Bar{...}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = Foo{
|
_ = Foo{
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
Bar{"A", "B"}, // ERROR "too many values in Bar literal" "too few values in Foo literal"
|
Bar{"A", "B"}, // ERROR "too many values in Bar{...}" "too few values in Foo{...}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ type P struct {
|
|||||||
type T struct{}
|
type T struct{}
|
||||||
|
|
||||||
var _ = S{
|
var _ = S{
|
||||||
f: &T{}, // ERROR "cannot use &T literal"
|
f: &T{}, // ERROR "cannot use &T{}"
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = P{
|
var _ = P{
|
||||||
f: T{}, // ERROR "cannot use T literal"
|
f: T{}, // ERROR "cannot use T{}"
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,5 @@ func debugf(format string, args ...interface{}) { // ERROR "can inline debugf" "
|
|||||||
|
|
||||||
func bar() { // ERROR "can inline bar"
|
func bar() { // ERROR "can inline bar"
|
||||||
value := 10
|
value := 10
|
||||||
debugf("value is %d", value) // ERROR "inlining call to debugf" "value does not escape" "\[\]interface {} literal does not escape"
|
debugf("value is %d", value) // ERROR "inlining call to debugf" "value does not escape" "\[\]interface {}{...} does not escape"
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,18 @@ func g() {
|
|||||||
defer f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$"
|
defer f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$"
|
||||||
|
|
||||||
defer f(nil...)
|
defer f(nil...)
|
||||||
defer f([]*int{}...) // ERROR "\[\]\*int literal does not escape$"
|
defer f([]*int{}...) // ERROR "\[\]\*int{} does not escape$"
|
||||||
defer f([]*int{new(int)}...) // ERROR "\[\]\*int literal does not escape$" "new\(int\) does not escape$"
|
defer f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$"
|
||||||
defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int literal does not escape$" "new\(int\) does not escape$"
|
defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$"
|
||||||
|
|
||||||
go f()
|
go f()
|
||||||
go f(new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
go f(new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
go f(new(int), new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
go f(new(int), new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
|
|
||||||
go f(nil...)
|
go f(nil...)
|
||||||
go f([]*int{}...) // ERROR "\[\]\*int literal escapes to heap$"
|
go f([]*int{}...) // ERROR "\[\]\*int{} escapes to heap$"
|
||||||
go f([]*int{new(int)}...) // ERROR "\[\]\*int literal escapes to heap$" "new\(int\) escapes to heap$"
|
go f([]*int{new(int)}...) // ERROR "\[\]\*int{...} escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int literal escapes to heap$" "new\(int\) escapes to heap$"
|
go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
|
|
||||||
for {
|
for {
|
||||||
defer f()
|
defer f()
|
||||||
@ -33,17 +33,17 @@ func g() {
|
|||||||
defer f(new(int), new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
defer f(new(int), new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
|
|
||||||
defer f(nil...)
|
defer f(nil...)
|
||||||
defer f([]*int{}...) // ERROR "\[\]\*int literal escapes to heap$"
|
defer f([]*int{}...) // ERROR "\[\]\*int{} escapes to heap$"
|
||||||
defer f([]*int{new(int)}...) // ERROR "\[\]\*int literal escapes to heap$" "new\(int\) escapes to heap$"
|
defer f([]*int{new(int)}...) // ERROR "\[\]\*int{...} escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int literal escapes to heap$" "new\(int\) escapes to heap$"
|
defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
|
|
||||||
go f()
|
go f()
|
||||||
go f(new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
go f(new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
go f(new(int), new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
go f(new(int), new(int)) // ERROR "... argument escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
|
|
||||||
go f(nil...)
|
go f(nil...)
|
||||||
go f([]*int{}...) // ERROR "\[\]\*int literal escapes to heap$"
|
go f([]*int{}...) // ERROR "\[\]\*int{} escapes to heap$"
|
||||||
go f([]*int{new(int)}...) // ERROR "\[\]\*int literal escapes to heap$" "new\(int\) escapes to heap$"
|
go f([]*int{new(int)}...) // ERROR "\[\]\*int{...} escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int literal escapes to heap$" "new\(int\) escapes to heap$"
|
go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} escapes to heap$" "new\(int\) escapes to heap$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
test/fixedbugs/issue38745.go
Normal file
19
test/fixedbugs/issue38745.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// errorcheck
|
||||||
|
|
||||||
|
// Copyright 2020 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 t struct{ x int }
|
||||||
|
|
||||||
|
func f1() {
|
||||||
|
t{}.M() // ERROR "t{}.M undefined \(type t has no field or method M\)"
|
||||||
|
t{x: 1}.M() // ERROR "t{...}.M undefined \(type t has no field or method M\)"
|
||||||
|
}
|
||||||
|
|
||||||
|
func f2() (*t, error) {
|
||||||
|
// BAD: should report undefined error only.
|
||||||
|
return t{}.M() // ERROR "t{}.M undefined \(type t has no field or method M\)" "not enough arguments to return"
|
||||||
|
}
|
@ -12,18 +12,18 @@ func (t) f() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func x() {
|
func x() {
|
||||||
x := t{}.f // ERROR "t literal.f escapes to heap"
|
x := t{}.f // ERROR "t{}.f escapes to heap"
|
||||||
x()
|
x()
|
||||||
}
|
}
|
||||||
|
|
||||||
func y() {
|
func y() {
|
||||||
var i int // ERROR "moved to heap: i"
|
var i int // ERROR "moved to heap: i"
|
||||||
y := (&t{&i}).f // ERROR "\(&t literal\).f escapes to heap" "&t literal escapes to heap"
|
y := (&t{&i}).f // ERROR "\(&t{...}\).f escapes to heap" "&t{...} escapes to heap"
|
||||||
y()
|
y()
|
||||||
}
|
}
|
||||||
|
|
||||||
func z() {
|
func z() {
|
||||||
var i int // ERROR "moved to heap: i"
|
var i int // ERROR "moved to heap: i"
|
||||||
z := t{&i}.f // ERROR "t literal.f escapes to heap"
|
z := t{&i}.f // ERROR "t{...}.f escapes to heap"
|
||||||
z()
|
z()
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
package p
|
package p
|
||||||
|
|
||||||
func f() [2]int {
|
func f() [2]int {
|
||||||
return [...]int{2: 0} // ERROR "cannot use \[\.\.\.\]int literal \(type \[3\]int\)"
|
return [...]int{2: 0} // ERROR "cannot use \[\.\.\.\]int{...} \(type \[3\]int\)"
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,12 @@ func bufferNotEscape() string {
|
|||||||
// can be stack-allocated.
|
// can be stack-allocated.
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
b.WriteString("123")
|
b.WriteString("123")
|
||||||
b.Write([]byte{'4'}) // ERROR "\[\]byte literal does not escape$"
|
b.Write([]byte{'4'}) // ERROR "\[\]byte{...} does not escape$"
|
||||||
return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$"
|
return b.String() // ERROR "inlining call to bytes.\(\*Buffer\).String$" "string\(bytes.b.buf\[bytes.b.off:\]\) escapes to heap$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func bufferNoEscape2(xs []string) int { // ERROR "xs does not escape$"
|
func bufferNoEscape2(xs []string) int { // ERROR "xs does not escape$"
|
||||||
b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
|
b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "&bytes.Buffer{...} does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
|
||||||
for _, x := range xs {
|
for _, x := range xs {
|
||||||
b.WriteString(x)
|
b.WriteString(x)
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ func bufferNoEscape2(xs []string) int { // ERROR "xs does not escape$"
|
|||||||
}
|
}
|
||||||
|
|
||||||
func bufferNoEscape3(xs []string) string { // ERROR "xs does not escape$"
|
func bufferNoEscape3(xs []string) string { // ERROR "xs does not escape$"
|
||||||
b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
|
b := bytes.NewBuffer(make([]byte, 0, 64)) // ERROR "&bytes.Buffer{...} does not escape$" "make\(\[\]byte, 0, 64\) does not escape$" "inlining call to bytes.NewBuffer$"
|
||||||
for _, x := range xs {
|
for _, x := range xs {
|
||||||
b.WriteString(x)
|
b.WriteString(x)
|
||||||
b.WriteByte(',')
|
b.WriteByte(',')
|
||||||
@ -41,13 +41,13 @@ func bufferNoEscape3(xs []string) string { // ERROR "xs does not escape$"
|
|||||||
|
|
||||||
func bufferNoEscape4() []byte {
|
func bufferNoEscape4() []byte {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
b.Grow(64) // ERROR "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m·3\]$" "inlining call to bytes.\(\*Buffer\).Grow$"
|
b.Grow(64) // ERROR "bufferNoEscape4 ignoring self-assignment in bytes.b.buf = bytes.b.buf\[:bytes.m·3\]$" "inlining call to bytes.\(\*Buffer\).Grow$"
|
||||||
useBuffer(&b)
|
useBuffer(&b)
|
||||||
return b.Bytes() // ERROR "inlining call to bytes.\(\*Buffer\).Bytes$"
|
return b.Bytes() // ERROR "inlining call to bytes.\(\*Buffer\).Bytes$"
|
||||||
}
|
}
|
||||||
|
|
||||||
func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5$"
|
func bufferNoEscape5() { // ERROR "can inline bufferNoEscape5$"
|
||||||
b := bytes.NewBuffer(make([]byte, 0, 128)) // ERROR "&bytes.Buffer literal does not escape$" "make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$"
|
b := bytes.NewBuffer(make([]byte, 0, 128)) // ERROR "&bytes.Buffer{...} does not escape$" "make\(\[\]byte, 0, 128\) does not escape$" "inlining call to bytes.NewBuffer$"
|
||||||
useBuffer(b)
|
useBuffer(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,6 @@ func head(xs ...string) string { // ERROR "can inline head" "leaking param: xs t
|
|||||||
}
|
}
|
||||||
|
|
||||||
func f() string { // ERROR "can inline f"
|
func f() string { // ERROR "can inline f"
|
||||||
x := head("hello", "world") // ERROR "inlining call to head" "\[\]string literal does not escape"
|
x := head("hello", "world") // ERROR "inlining call to head" "\[\]string{...} does not escape"
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user