modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/fixedbugs/issue12006.go (about) 1 // errorcheck -0 -m -l 2 3 // Copyright 2015 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Test escape analysis through ... parameters. 8 9 package foo 10 11 func FooN(vals ...*int) (s int) { // ERROR "FooN vals does not escape" 12 for _, v := range vals { 13 s += *v 14 } 15 return s 16 } 17 18 // Append forces heap allocation and copies entries in vals to heap, therefore they escape to heap. 19 func FooNx(x *int, vals ...*int) (s int) { // ERROR "leaking param: x" "leaking param content: vals" 20 vals = append(vals, x) 21 return FooN(vals...) 22 } 23 24 var sink []*int 25 26 func FooNy(x *int, vals ...*int) (s int) { // ERROR "leaking param: x" "leaking param: vals" "leaking param content: vals" 27 vals = append(vals, x) 28 sink = vals 29 return FooN(vals...) 30 } 31 32 func FooNz(vals ...*int) (s int) { // ERROR "leaking param: vals" 33 sink = vals 34 return FooN(vals...) 35 } 36 37 func TFooN() { 38 for i := 0; i < 1000; i++ { 39 var i, j int 40 FooN(&i, &j) // ERROR "TFooN &i does not escape" "TFooN &j does not escape" "TFooN ... argument does not escape" 41 } 42 } 43 44 func TFooNx() { 45 for i := 0; i < 1000; i++ { 46 var i, j, k int // ERROR "moved to heap: i" "moved to heap: j" "moved to heap: k" 47 FooNx(&k, &i, &j) // ERROR "&k escapes to heap" "&i escapes to heap" "&j escapes to heap" "TFooNx ... argument does not escape" 48 } 49 } 50 51 func TFooNy() { 52 for i := 0; i < 1000; i++ { 53 var i, j, k int // ERROR "moved to heap: i" "moved to heap: j" "moved to heap: k" 54 FooNy(&k, &i, &j) // ERROR "&i escapes to heap" "&j escapes to heap" "&k escapes to heap" "... argument escapes to heap" 55 } 56 } 57 58 func TFooNz() { 59 for i := 0; i < 1000; i++ { 60 var i, j int // ERROR "moved to heap: i" "moved to heap: j" 61 FooNz(&i, &j) // ERROR "&i escapes to heap" "&j escapes to heap" "... argument escapes to heap" 62 } 63 } 64 65 var isink *int32 66 67 func FooI(args ...interface{}) { // ERROR "leaking param content: args" 68 for i := 0; i < len(args); i++ { 69 switch x := args[i].(type) { 70 case nil: 71 println("is nil") 72 case int32: 73 println("is int32") 74 case *int32: 75 println("is *int32") 76 isink = x 77 case string: 78 println("is string") 79 } 80 } 81 } 82 83 func TFooI() { 84 a := int32(1) // ERROR "moved to heap: a" 85 b := "cat" 86 c := &a // ERROR "&a escapes to heap" 87 FooI(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooI ... argument does not escape" 88 } 89 90 func FooJ(args ...interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1" 91 for i := 0; i < len(args); i++ { 92 switch x := args[i].(type) { 93 case nil: 94 println("is nil") 95 case int32: 96 println("is int32") 97 case *int32: 98 println("is *int32") 99 return x 100 case string: 101 println("is string") 102 } 103 } 104 return nil 105 } 106 107 func TFooJ1() { 108 a := int32(1) 109 b := "cat" 110 c := &a // ERROR "TFooJ1 &a does not escape" 111 FooJ(a, b, c) // ERROR "TFooJ1 a does not escape" "TFooJ1 b does not escape" "TFooJ1 c does not escape" "TFooJ1 ... argument does not escape" 112 } 113 114 func TFooJ2() { 115 a := int32(1) // ERROR "moved to heap: a" 116 b := "cat" 117 c := &a // ERROR "&a escapes to heap" 118 isink = FooJ(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooJ2 ... argument does not escape" 119 } 120 121 type fakeSlice struct { 122 l int 123 a *[4]interface{} 124 } 125 126 func FooK(args fakeSlice) *int32 { // ERROR "leaking param: args to result ~r1 level=1" 127 for i := 0; i < args.l; i++ { 128 switch x := (*args.a)[i].(type) { 129 case nil: 130 println("is nil") 131 case int32: 132 println("is int32") 133 case *int32: 134 println("is *int32") 135 return x 136 case string: 137 println("is string") 138 } 139 } 140 return nil 141 } 142 143 func TFooK2() { 144 a := int32(1) // ERROR "moved to heap: a" 145 b := "cat" 146 c := &a // ERROR "&a escapes to heap" 147 fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooK2 &\[4\]interface {} literal does not escape" 148 isink = FooK(fs) 149 } 150 151 func FooL(args []interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1" 152 for i := 0; i < len(args); i++ { 153 switch x := args[i].(type) { 154 case nil: 155 println("is nil") 156 case int32: 157 println("is int32") 158 case *int32: 159 println("is *int32") 160 return x 161 case string: 162 println("is string") 163 } 164 } 165 return nil 166 } 167 168 func TFooL2() { 169 a := int32(1) // ERROR "moved to heap: a" 170 b := "cat" 171 c := &a // ERROR "&a escapes to heap" 172 s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooL2 \[\]interface {} literal does not escape" 173 isink = FooL(s) 174 }