1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Check correctness of various closure corner cases
6 // that are expected to be inlined
15 if x := func() int { // ERROR "can inline main.func1"
17 }(); x != 1 { // ERROR "inlining call to main.func1"
20 if x := func() int { // ERROR "can inline main.func2" "func literal does not escape"
22 }; x() != 1 { // ERROR "inlining call to main.func2"
28 if y := func(x int) int { // ERROR "can inline main.func3"
30 }(40); y != 42 { // ERROR "inlining call to main.func3"
33 if y := func(x int) int { // ERROR "can inline main.func4" "func literal does not escape"
35 }; y(40) != 42 { // ERROR "inlining call to main.func4"
41 y := func(x int) int { // ERROR "can inline main.func5" "func literal does not escape"
44 y = func(x int) int { // ERROR "can inline main.func6" "func literal does not escape"
53 func() { // ERROR "func literal does not escape"
54 y := func(x int) int { // ERROR "can inline main.func7.1" "func literal does not escape"
57 y = func(x int) int { // ERROR "can inline main.func7.2" "func literal does not escape"
67 y := func(x int) int { // ERROR "can inline main.func8" "func literal does not escape"
70 y, sink = func(x int) int { // ERROR "can inline main.func9" "func literal does not escape"
79 func() { // ERROR "func literal does not escape"
80 y := func(x int) int { // ERROR "can inline main.func10.1" "func literal does not escape"
83 y, sink = func(x int) int { // ERROR "can inline main.func10.2" "func literal does not escape"
93 y := func(x int) int { // ERROR "can inline main.func11" "func literal does not escape"
96 y, sink = func() (func(int) int, int) { // ERROR "can inline main.func12"
97 return func(x int) int { // ERROR "can inline main.func12"
100 }() // ERROR "func literal does not escape" "inlining call to main.func12"
102 ppanic("y(40) != 41")
107 func() { // ERROR "func literal does not escape"
108 y := func(x int) int { // ERROR "func literal does not escape" "can inline main.func13.1"
111 y, sink = func() (func(int) int, int) { // ERROR "can inline main.func13.2"
112 return func(x int) int { // ERROR "can inline main.func13.2"
115 }() // ERROR "func literal does not escape" "inlining call to main.func13.2"
117 ppanic("y(40) != 41")
123 y := func(x int) int { // ERROR "can inline main.func14" "func literal does not escape"
126 y, ok = map[int]func(int) int{ // ERROR "does not escape"
127 0: func(x int) int { return x + 1 }, // ERROR "can inline main.func15" "func literal escapes"
130 ppanic("y(40) != 41")
135 func() { // ERROR "func literal does not escape"
136 y := func(x int) int { // ERROR "can inline main.func16.1" "func literal does not escape"
139 y, ok = map[int]func(int) int{ // ERROR "does not escape"
140 0: func(x int) int { return x + 1 }, // ERROR "can inline main.func16.2" "func literal escapes"
143 ppanic("y(40) != 41")
149 y := func(x int) int { // ERROR "can inline main.func17" "func literal does not escape"
152 y, ok = interface{}(func(x int) int { // ERROR "can inline main.func18" "does not escape"
156 ppanic("y(40) != 41")
161 func() { // ERROR "func literal does not escape"
162 y := func(x int) int { // ERROR "can inline main.func19.1" "func literal does not escape"
165 y, ok = interface{}(func(x int) int { // ERROR "can inline main.func19.2" "does not escape"
169 ppanic("y(40) != 41")
176 if y := func() int { // ERROR "can inline main.func20"
178 }(); y != 42 { // ERROR "inlining call to main.func20"
181 if y := func() int { // ERROR "can inline main.func21" "func literal does not escape"
183 }; y() != 42 { // ERROR "inlining call to main.func21"
190 if z := func(y int) int { // ERROR "can inline main.func22"
191 return func() int { // ERROR "can inline main.func22.1" "can inline main.main.func22.func30"
193 }() // ERROR "inlining call to main.func22.1"
194 }(1); z != 43 { // ERROR "inlining call to main.func22" "inlining call to main.main.func22.func30"
197 if z := func(y int) int { // ERROR "func literal does not escape" "can inline main.func23"
198 return func() int { // ERROR "can inline main.func23.1" "can inline main.main.func23.func31"
200 }() // ERROR "inlining call to main.func23.1"
201 }; z(1) != 43 { // ERROR "inlining call to main.func23" "inlining call to main.main.func23.func31"
208 func() { // ERROR "can inline main.func24"
209 func() { // ERROR "can inline main.func24" "can inline main.main.func24.func32"
211 }() // ERROR "inlining call to main.func24"
212 }() // ERROR "inlining call to main.func24" "inlining call to main.main.func24.func32"
220 func(b int) { // ERROR "func literal does not escape"
221 func() { // ERROR "can inline main.func25.1"
223 }() // ERROR "inlining call to main.func25.1"
235 func() { // ERROR "can inline main.func26"
241 recover() // prevent inlining
243 }() // ERROR "inlining call to main.func26" "func literal does not escape"
251 // This has an unfortunate exponential growth, where as we visit each
252 // function, we inline the inner closure, and that constructs a new
253 // function for any closures inside the inner function, and then we
254 // revisit those. E.g., func34 and func36 are constructed by the inliner.
255 if r := func(x int) int { // ERROR "can inline main.func27"
257 return func(y int) int { // ERROR "can inline main.func27.1" "can inline main.main.func27.func34"
259 return func(z int) int { // ERROR "can inline main.func27.1.1" "can inline main.main.func27.func34.1" "can inline main.func27.main.func27.1.2" "can inline main.main.func27.main.main.func27.func34.func36"
260 return a*x + b*y + c*z
261 }(10) // ERROR "inlining call to main.func27.1.1"
262 }(100) // ERROR "inlining call to main.func27.1" "inlining call to main.func27.main.func27.1.2"
263 }(1000); r != 2350 { // ERROR "inlining call to main.func27" "inlining call to main.main.func27.func34" "inlining call to main.main.func27.main.main.func27.func34.func36"
270 if r := func(x int) int { // ERROR "can inline main.func28"
272 return func(y int) int { // ERROR "can inline main.func28.1" "can inline main.main.func28.func35"
274 func(z int) { // ERROR "can inline main.func28.1.1" "can inline main.func28.main.func28.1.2" "can inline main.main.func28.func35.1" "can inline main.main.func28.main.main.func28.func35.func37"
278 }(10) // ERROR "inlining call to main.func28.1.1"
280 }(100) + b // ERROR "inlining call to main.func28.1" "inlining call to main.func28.main.func28.1.2"
281 }(1000); r != 2350 { // ERROR "inlining call to main.func28" "inlining call to main.main.func28.func35" "inlining call to main.main.func28.main.main.func28.func35.func37"
291 func ppanic(s string) { // ERROR "leaking param: s"
292 panic(s) // ERROR "s escapes to heap"