| // errorcheck -0 -m -l |
| |
| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Test escape analysis for maps. |
| |
| package escape |
| |
| var sink interface{} |
| |
| func map0() { |
| m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape" |
| // BAD: i should not escape |
| i := 0 // ERROR "moved to heap: i" |
| // BAD: j should not escape |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| _ = m |
| } |
| |
| func map1() *int { |
| m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape" |
| // BAD: i should not escape |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| return m[&i] |
| } |
| |
| func map2() map[*int]*int { |
| m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) escapes to heap" |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| return m |
| } |
| |
| func map3() []*int { |
| m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape" |
| i := 0 // ERROR "moved to heap: i" |
| // BAD: j should not escape |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| var r []*int |
| for k := range m { |
| r = append(r, k) |
| } |
| return r |
| } |
| |
| func map4() []*int { |
| m := make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape" |
| // BAD: i should not escape |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| var r []*int |
| for k, v := range m { |
| // We want to test exactly "for k, v := range m" rather than "for _, v := range m". |
| // The following if is merely to use (but not leak) k. |
| if k != nil { |
| r = append(r, v) |
| } |
| } |
| return r |
| } |
| |
| func map5(m map[*int]*int) { // ERROR "m does not escape" |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| } |
| |
| func map6(m map[*int]*int) { // ERROR "m does not escape" |
| if m != nil { |
| m = make(map[*int]*int) // ERROR "make\(map\[\*int\]\*int\) does not escape" |
| } |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m[&i] = &j |
| } |
| |
| func map7() { |
| // BAD: i should not escape |
| i := 0 // ERROR "moved to heap: i" |
| // BAD: j should not escape |
| j := 0 // ERROR "moved to heap: j" |
| m := map[*int]*int{&i: &j} // ERROR "map\[\*int\]\*int{...} does not escape" |
| _ = m |
| } |
| |
| func map8() { |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m := map[*int]*int{&i: &j} // ERROR "map\[\*int\]\*int{...} escapes to heap" |
| sink = m |
| } |
| |
| func map9() *int { |
| // BAD: i should not escape |
| i := 0 // ERROR "moved to heap: i" |
| j := 0 // ERROR "moved to heap: j" |
| m := map[*int]*int{&i: &j} // ERROR "map\[\*int\]\*int{...} does not escape" |
| return m[nil] |
| } |