1 // errorcheckwithauto -0 -m -d=inlfuncswithclosures=1
3 //go:build !goexperiment.newinliner
4 // +build !goexperiment.newinliner
6 // Copyright 2015 The Go Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style
8 // license that can be found in the LICENSE file.
10 // Test, using compiler diagnostic flags, that inlining is working.
11 // Compiles but does not run.
21 func add2(p *byte, n uintptr) *byte { // ERROR "can inline add2" "leaking param: p to result"
22 return (*byte)(add1(unsafe.Pointer(p), n)) // ERROR "inlining call to add1"
25 func add1(p unsafe.Pointer, x uintptr) unsafe.Pointer { // ERROR "can inline add1" "leaking param: p to result"
26 return unsafe.Pointer(uintptr(p) + x)
29 func f(x *byte) *byte { // ERROR "can inline f" "leaking param: x to result"
30 return add2(x, 1) // ERROR "inlining call to add2" "inlining call to add1"
38 func h(x int) int { // ERROR "can inline h"
42 func i(x int) int { // ERROR "can inline i"
47 func j(x int) int { // ERROR "can inline j"
56 func f2() int { // ERROR "can inline f2"
59 return tmp2(0) // ERROR "inlining call to h"
62 var abc = errors.New("abc") // ERROR "inlining call to errors.New"
64 var somethingWrong error
66 // local closures can be inlined
67 func l(x, y int) (int, int, error) { // ERROR "can inline l"
68 e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result"
72 e(somethingWrong) // ERROR "inlining call to l.func1"
75 f(nil) // ERROR "inlining call to l.func1"
80 // any re-assignment prevents closure inlining
82 foo := func() int { return 1 } // ERROR "can inline m.func1" "func literal does not escape"
84 foo = func() int { return 2 } // ERROR "can inline m.func2" "func literal does not escape"
88 // address taking prevents closure inlining
90 foo := func() int { return 1 } // ERROR "can inline n.func1" "func literal does not escape"
96 // make sure assignment inside closure is detected
98 foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape"
99 func(x int) { // ERROR "can inline o.func2"
101 foo = func() int { return 2 } // ERROR "can inline o.func2"
103 }(11) // ERROR "func literal does not escape" "inlining call to o.func2"
107 func p() int { // ERROR "can inline p"
108 return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1"
111 func q(x int) int { // ERROR "can inline q"
112 foo := func() int { return x * 2 } // ERROR "can inline q.func1" "func literal does not escape"
113 return foo() // ERROR "inlining call to q.func1"
117 foo := func(x int) int { // ERROR "can inline r.func1" "func literal does not escape"
120 bar := func(x int) int { // ERROR "func literal does not escape" "can inline r.func2"
121 return x + func(y int) int { // ERROR "can inline r.func2.1" "can inline r.r.func2.func3"
123 }(x) // ERROR "inlining call to r.func2.1"
125 return foo(42) + bar(42) // ERROR "inlining call to r.func1" "inlining call to r.func2" "inlining call to r.r.func2.func3"
128 func s0(x int) int { // ERROR "can inline s0"
129 foo := func() { // ERROR "can inline s0.func1" "func literal does not escape"
132 foo() // ERROR "inlining call to s0.func1"
136 func s1(x int) int { // ERROR "can inline s1"
137 foo := func() int { // ERROR "can inline s1.func1" "func literal does not escape"
141 return foo() // ERROR "inlining call to s1.func1"
144 func switchBreak(x, y int) int { // ERROR "can inline switchBreak"
160 func switchType(x interface{}) int { // ERROR "can inline switchType" "x does not escape"
169 // Test that switches on constant things, with constant cases, only cost anything for
170 // the case that matches. See issue 50253.
171 func switchConst1(p func(string)) { // ERROR "can inline switchConst" "p does not escape"
185 func switchConst2() string { // ERROR "can inline switchConst2"
186 switch runtime.GOOS {
193 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":
199 func switchConst3() string { // ERROR "can inline switchConst3"
200 switch runtime.GOOS {
207 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":
213 func switchConst4() { // ERROR "can inline switchConst4"
214 const intSize = 32 << (^uint(0) >> 63)
215 want := func() string { // ERROR "can inline switchConst4.func1"
224 }() // ERROR "inlining call to switchConst4.func1"
228 func inlineRangeIntoMe(data []int) { // ERROR "can inline inlineRangeIntoMe" "data does not escape"
229 rangeFunc(data, 12) // ERROR "inlining call to rangeFunc"
232 func rangeFunc(xs []int, b int) int { // ERROR "can inline rangeFunc" "xs does not escape"
233 for i, x := range xs {
243 func (T) meth(int, int) {} // ERROR "can inline T.meth"
245 func k() (T, int, int) { return T{}, 0, 0 } // ERROR "can inline k"
247 func f3() { // ERROR "can inline f3"
248 T.meth(k()) // ERROR "inlining call to k" "inlining call to T.meth"
249 // ERRORAUTO "inlining call to T.meth"
252 func small1() { // ERROR "can inline small1"
255 func small2() int { // ERROR "can inline small2"
256 return runtime.GOMAXPROCS(0)
258 func small3(t T) { // ERROR "can inline small3"
261 func small4(t T) { // not inlineable - has 2 calls.
262 t.meth2(runtime.GOMAXPROCS(0), 5)
264 func (T) meth2(int, int) { // not inlineable - has 2 calls.
269 // Issue #29737 - make sure we can do inlining for a chain of recursive functions
270 func ee() { // ERROR "can inline ee"
271 ff(100) // ERROR "inlining call to ff" "inlining call to gg" "inlining call to hh"
274 func ff(x int) { // ERROR "can inline ff"
278 gg(x - 1) // ERROR "inlining call to gg" "inlining call to hh"
280 func gg(x int) { // ERROR "can inline gg"
281 hh(x - 1) // ERROR "inlining call to hh" "inlining call to ff"
283 func hh(x int) { // ERROR "can inline hh"
284 ff(x - 1) // ERROR "inlining call to ff" "inlining call to gg"
287 // Issue #14768 - make sure we can inline for loops.
288 func for1(fn func() bool) { // ERROR "can inline for1" "fn does not escape"
298 func for2(fn func() bool) { // ERROR "can inline for2" "fn does not escape"
309 // Issue #18493 - make sure we can do inlining of functions with a method value
312 func (a T1) meth(val int) int { // ERROR "can inline T1.meth"
316 func getMeth(t1 T1) func(int) int { // ERROR "can inline getMeth"
317 return t1.meth // ERROR "t1.meth escapes to heap"
318 // ERRORAUTO "inlining call to T1.meth"
321 func ii() { // ERROR "can inline ii"
323 f := getMeth(t1) // ERROR "inlining call to getMeth" "t1.meth does not escape"
327 // Issue #42194 - make sure that functions evaluated in
328 // go and defer statements can be inlined.
330 defer gd1(gd2()) // ERROR "inlining call to gd2"
331 defer gd3()() // ERROR "inlining call to gd3"
332 go gd1(gd2()) // ERROR "inlining call to gd2"
333 go gd3()() // ERROR "inlining call to gd3"
336 func gd2() int { // ERROR "can inline gd2"
340 func gd3() func() { // ERROR "can inline gd3"
344 // Issue #42788 - ensure ODEREF OCONVNOP* OADDR is low cost.
345 func EncodeQuad(d []uint32, x [6]float32) { // ERROR "can inline EncodeQuad" "d does not escape"
347 d[0] = float32bits(x[0]) // ERROR "inlining call to float32bits"
348 d[1] = float32bits(x[1]) // ERROR "inlining call to float32bits"
349 d[2] = float32bits(x[2]) // ERROR "inlining call to float32bits"
350 d[3] = float32bits(x[3]) // ERROR "inlining call to float32bits"
351 d[4] = float32bits(x[4]) // ERROR "inlining call to float32bits"
352 d[5] = float32bits(x[5]) // ERROR "inlining call to float32bits"
355 // float32bits is a copy of math.Float32bits to ensure that
356 // these tests pass with `-gcflags=-l`.
357 func float32bits(f float32) uint32 { // ERROR "can inline float32bits"
358 return *(*uint32)(unsafe.Pointer(&f))
361 // Ensure OCONVNOP is zero cost.
362 func Conv(v uint64) uint64 { // ERROR "can inline Conv"
363 return conv2(conv2(conv2(v))) // ERROR "inlining call to (conv1|conv2)"
365 func conv2(v uint64) uint64 { // ERROR "can inline conv2"
366 return conv1(conv1(conv1(conv1(v)))) // ERROR "inlining call to conv1"
368 func conv1(v uint64) uint64 { // ERROR "can inline conv1"
369 return uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(uint64(v)))))))))))
372 func select1(x, y chan bool) int { // ERROR "can inline select1" "x does not escape" "y does not escape"
381 func select2(x, y chan bool) { // ERROR "can inline select2" "x does not escape" "y does not escape"
382 loop: // test that labeled select can be inlined.
390 func inlineSelect2(x, y chan bool) { // ERROR "can inline inlineSelect2" ERROR "x does not escape" "y does not escape"
392 for i := 0; i < 5; i++ {
396 select2(x, y) // ERROR "inlining call to select2"
400 // Issue #62211: inlining a function with unreachable "return"
401 // statements could trip up phi insertion.
402 func issue62211(x bool) { // ERROR "can inline issue62211"
403 if issue62211F(x) { // ERROR "inlining call to issue62211F"
405 if issue62211G(x) { // ERROR "inlining call to issue62211G"
408 // Initial fix CL caused a "non-monotonic scope positions" failure
409 // on code like this.
415 func issue62211F(x bool) bool { // ERROR "can inline issue62211F"
422 func issue62211G(x bool) bool { // ERROR "can inline issue62211G"