1 // errorcheckwithauto -0 -m -d=inlfuncswithclosures=1
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.
7 // Test, using compiler diagnostic flags, that inlining is working.
8 // Compiles but does not run.
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"
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)
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"
34 func h(x int) int { // ERROR "can inline h"
38 func i(x int) int { // ERROR "can inline i"
43 func j(x int) int { // ERROR "can inline j"
52 func f2() int { // ERROR "can inline f2"
55 return tmp2(0) // ERROR "inlining call to h"
58 var somethingWrong error
60 // local closures can be inlined
61 func l(x, y int) (int, int, error) { // ERROR "can inline l"
62 e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result"
66 e(somethingWrong) // ERROR "inlining call to l.func1"
69 f(nil) // ERROR "inlining call to l.func1"
74 // any re-assignment prevents closure inlining
76 foo := func() int { return 1 } // ERROR "can inline m.func1" "func literal does not escape"
78 foo = func() int { return 2 } // ERROR "can inline m.func2" "func literal does not escape"
82 // address taking prevents closure inlining
84 foo := func() int { return 1 } // ERROR "can inline n.func1" "func literal does not escape"
90 // make sure assignment inside closure is detected
92 foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape"
93 func(x int) { // ERROR "can inline o.func2"
95 foo = func() int { return 2 } // ERROR "can inline o.func2"
97 }(11) // ERROR "func literal does not escape" "inlining call to o.func2"
101 func p() int { // ERROR "can inline p"
102 return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1"
105 func q(x int) int { // ERROR "can inline q"
106 foo := func() int { return x * 2 } // ERROR "can inline q.func1" "func literal does not escape"
107 return foo() // ERROR "inlining call to q.func1"
111 foo := func(x int) int { // ERROR "can inline r.func1" "func literal does not escape"
114 bar := func(x int) int { // ERROR "func literal does not escape" "can inline r.func2"
115 return x + func(y int) int { // ERROR "can inline r.func2.1" "can inline r.func3"
117 }(x) // ERROR "inlining call to r.func2.1"
119 return foo(42) + bar(42) // ERROR "inlining call to r.func1" "inlining call to r.func2" "inlining call to r.func3"
122 func s0(x int) int { // ERROR "can inline s0"
123 foo := func() { // ERROR "can inline s0.func1" "func literal does not escape"
126 foo() // ERROR "inlining call to s0.func1"
130 func s1(x int) int { // ERROR "can inline s1"
131 foo := func() int { // ERROR "can inline s1.func1" "func literal does not escape"
135 return foo() // ERROR "inlining call to s1.func1"
138 func switchBreak(x, y int) int { // ERROR "can inline switchBreak"
154 func switchType(x interface{}) int { // ERROR "can inline switchType" "x does not escape"
163 // Test that switches on constant things, with constant cases, only cost anything for
164 // the case that matches. See issue 50253.
165 func switchConst1(p func(string)) { // ERROR "can inline switchConst" "p does not escape"
179 func switchConst2() string { // ERROR "can inline switchConst2"
180 switch runtime.GOOS {
187 case "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100":
193 func switchConst3() string { // ERROR "can inline switchConst3"
194 switch runtime.GOOS {
201 case "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100":
208 func inlineRangeIntoMe(data []int) { // ERROR "can inline inlineRangeIntoMe" "data does not escape"
209 rangeFunc(data, 12) // ERROR "inlining call to rangeFunc"
212 func rangeFunc(xs []int, b int) int { // ERROR "can inline rangeFunc" "xs does not escape"
213 for i, x := range xs {
223 func (T) meth(int, int) {} // ERROR "can inline T.meth"
225 func k() (T, int, int) { return T{}, 0, 0 } // ERROR "can inline k"
227 func f3() { // ERROR "can inline f3"
228 T.meth(k()) // ERROR "inlining call to k" "inlining call to T.meth"
229 // ERRORAUTO "inlining call to T.meth"
232 func small1() { // ERROR "can inline small1"
235 func small2() int { // ERROR "can inline small2"
236 return runtime.GOMAXPROCS(0)
238 func small3(t T) { // ERROR "can inline small3"
241 func small4(t T) { // not inlineable - has 2 calls.
242 t.meth2(runtime.GOMAXPROCS(0), 5)
244 func (T) meth2(int, int) { // not inlineable - has 2 calls.
249 // Issue #29737 - make sure we can do inlining for a chain of recursive functions
250 func ee() { // ERROR "can inline ee"
251 ff(100) // ERROR "inlining call to ff" "inlining call to gg" "inlining call to hh"
254 func ff(x int) { // ERROR "can inline ff"
260 func gg(x int) { // ERROR "can inline gg"
263 func hh(x int) { // ERROR "can inline hh"
264 ff(x - 1) // ERROR "inlining call to ff" // ERROR "inlining call to gg"
267 // Issue #14768 - make sure we can inline for loops.
268 func for1(fn func() bool) { // ERROR "can inline for1" "fn does not escape"
278 func for2(fn func() bool) { // ERROR "can inline for2" "fn does not escape"
289 // Issue #18493 - make sure we can do inlining of functions with a method value
292 func (a T1) meth(val int) int { // ERROR "can inline T1.meth"
296 func getMeth(t1 T1) func(int) int { // ERROR "can inline getMeth"
297 return t1.meth // ERROR "t1.meth escapes to heap"
298 // ERRORAUTO "inlining call to T1.meth"
301 func ii() { // ERROR "can inline ii"
303 f := getMeth(t1) // ERROR "inlining call to getMeth" "t1.meth does not escape"
307 // Issue #42194 - make sure that functions evaluated in
308 // go and defer statements can be inlined.
310 defer gd1(gd2()) // ERROR "inlining call to gd2"
311 defer gd3()() // ERROR "inlining call to gd3"
312 go gd1(gd2()) // ERROR "inlining call to gd2"
313 go gd3()() // ERROR "inlining call to gd3"
316 func gd2() int { // ERROR "can inline gd2"
320 func gd3() func() { // ERROR "can inline gd3"
324 // Issue #42788 - ensure ODEREF OCONVNOP* OADDR is low cost.
325 func EncodeQuad(d []uint32, x [6]float32) { // ERROR "can inline EncodeQuad" "d does not escape"
327 d[0] = float32bits(x[0]) // ERROR "inlining call to float32bits"
328 d[1] = float32bits(x[1]) // ERROR "inlining call to float32bits"
329 d[2] = float32bits(x[2]) // ERROR "inlining call to float32bits"
330 d[3] = float32bits(x[3]) // ERROR "inlining call to float32bits"
331 d[4] = float32bits(x[4]) // ERROR "inlining call to float32bits"
332 d[5] = float32bits(x[5]) // ERROR "inlining call to float32bits"
335 // float32bits is a copy of math.Float32bits to ensure that
336 // these tests pass with `-gcflags=-l`.
337 func float32bits(f float32) uint32 { // ERROR "can inline float32bits"
338 return *(*uint32)(unsafe.Pointer(&f))
341 // Ensure OCONVNOP is zero cost.
342 func Conv(v uint64) uint64 { // ERROR "can inline Conv"
343 return conv2(conv2(conv2(v))) // ERROR "inlining call to (conv1|conv2)"
345 func conv2(v uint64) uint64 { // ERROR "can inline conv2"
346 return conv1(conv1(conv1(conv1(v)))) // ERROR "inlining call to conv1"
348 func conv1(v uint64) uint64 { // ERROR "can inline conv1"
349 return uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(v)))))))))))
352 func select1(x, y chan bool) int { // ERROR "can inline select1" "x does not escape" "y does not escape"
361 func select2(x, y chan bool) { // ERROR "can inline select2" "x does not escape" "y does not escape"
362 loop: // test that labeled select can be inlined.
370 func inlineSelect2(x, y chan bool) { // ERROR "can inline inlineSelect2" ERROR "x does not escape" "y does not escape"
372 for i := 0; i < 5; i++ {
376 select2(x, y) // ERROR "inlining call to select2"