modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/inline.go (about) 1 // errorcheck -0 -m 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, using compiler diagnostic flags, that inlining is working. 8 // Compiles but does not run. 9 10 package foo 11 12 import ( 13 "errors" 14 "unsafe" 15 ) 16 17 func add2(p *byte, n uintptr) *byte { // ERROR "can inline add2" "leaking param: p to result" 18 return (*byte)(add1(unsafe.Pointer(p), n)) // ERROR "inlining call to add1" 19 } 20 21 func add1(p unsafe.Pointer, x uintptr) unsafe.Pointer { // ERROR "can inline add1" "leaking param: p to result" 22 return unsafe.Pointer(uintptr(p) + x) 23 } 24 25 func f(x *byte) *byte { // ERROR "can inline f" "leaking param: x to result" 26 return add2(x, 1) // ERROR "inlining call to add2" "inlining call to add1" 27 } 28 29 //go:noinline 30 func g(x int) int { 31 return x + 1 32 } 33 34 func h(x int) int { // ERROR "can inline h" 35 return x + 2 36 } 37 38 func i(x int) int { // ERROR "can inline i" 39 const y = 2 40 return x + y 41 } 42 43 func j(x int) int { // ERROR "can inline j" 44 switch { 45 case x > 0: 46 return x + 2 47 default: 48 return x + 1 49 } 50 } 51 52 var somethingWrong error = errors.New("something went wrong") 53 54 // local closures can be inlined 55 func l(x, y int) (int, int, error) { 56 e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result" 57 return 0, 0, err 58 } 59 if x == y { 60 e(somethingWrong) // ERROR "inlining call to l.func1" 61 } 62 return y, x, nil 63 } 64 65 // any re-assignment prevents closure inlining 66 func m() int { 67 foo := func() int { return 1 } // ERROR "can inline m.func1" "func literal does not escape" 68 x := foo() 69 foo = func() int { return 2 } // ERROR "can inline m.func2" "func literal does not escape" 70 return x + foo() 71 } 72 73 // address taking prevents closure inlining 74 func n() int { 75 foo := func() int { return 1 } // ERROR "can inline n.func1" "func literal does not escape" 76 bar := &foo // ERROR "&foo does not escape" 77 x := (*bar)() + foo() 78 return x 79 } 80 81 // make sure assignment inside closure is detected 82 func o() int { 83 foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape" 84 func(x int) { // ERROR "func literal does not escape" 85 if x > 10 { 86 foo = func() int { return 2 } // ERROR "can inline o.func2" "func literal escapes" 87 } 88 }(11) 89 return foo() 90 } 91 92 func p() int { 93 return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1" 94 } 95 96 func q(x int) int { 97 foo := func() int { return x * 2 } // ERROR "can inline q.func1" "q func literal does not escape" 98 return foo() // ERROR "inlining call to q.func1" 99 } 100 101 func r(z int) int { 102 foo := func(x int) int { // ERROR "can inline r.func1" "r func literal does not escape" 103 return x + z 104 } 105 bar := func(x int) int { // ERROR "r func literal does not escape" 106 return x + func(y int) int { // ERROR "can inline r.func2.1" 107 return 2*y + x*z 108 }(x) // ERROR "inlining call to r.func2.1" 109 } 110 return foo(42) + bar(42) // ERROR "inlining call to r.func1" 111 } 112 113 func s0(x int) int { 114 foo := func() { // ERROR "can inline s0.func1" "s0 func literal does not escape" 115 x = x + 1 116 } 117 foo() // ERROR "inlining call to s0.func1" "&x does not escape" 118 return x 119 } 120 121 func s1(x int) int { 122 foo := func() int { // ERROR "can inline s1.func1" "s1 func literal does not escape" 123 return x 124 } 125 x = x + 1 126 return foo() // ERROR "inlining call to s1.func1" "&x does not escape" 127 } 128 129 // can't currently inline functions with a break statement 130 func switchBreak(x, y int) int { 131 var n int 132 switch x { 133 case 0: 134 n = 1 135 Done: 136 switch y { 137 case 0: 138 n += 10 139 break Done 140 } 141 n = 2 142 } 143 return n 144 } 145 146 // can't currently inline functions with a type switch 147 func switchType(x interface{}) int { // ERROR "switchType x does not escape" 148 switch x.(type) { 149 case int: 150 return x.(int) 151 default: 152 return 0 153 } 154 } 155 156 type T struct{} 157 158 func (T) meth(int, int) {} // ERROR "can inline T.meth" 159 160 func k() (T, int, int) { return T{}, 0, 0 } // ERROR "can inline k" 161 162 func _() { // ERROR "can inline _" 163 T.meth(k()) // ERROR "inlining call to k" "inlining call to T.meth" 164 }