| 
									
										
										
										
											2015-02-24 12:19:01 -05:00
										 |  |  | // errorcheck -0 -m | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 14:32:26 -07:00
										 |  |  | // Copyright 2015 The Go Authors. All rights reserved. | 
					
						
							| 
									
										
										
										
											2015-02-24 12:19:01 -05:00
										 |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test, using compiler diagnostic flags, that inlining is working. | 
					
						
							|  |  |  | // Compiles but does not run. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package foo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-11-04 19:23:08 -08:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 	"unsafe" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2015-02-24 12:19:01 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | func add2(p *byte, n uintptr) *byte { // ERROR "can inline add2" "leaking param: p to result" | 
					
						
							|  |  |  | 	return (*byte)(add1(unsafe.Pointer(p), n)) // ERROR "inlining call to add1" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func add1(p unsafe.Pointer, x uintptr) unsafe.Pointer { // ERROR "can inline add1" "leaking param: p to result" | 
					
						
							|  |  |  | 	return unsafe.Pointer(uintptr(p) + x) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func f(x *byte) *byte { // ERROR "can inline f" "leaking param: x to result" | 
					
						
							|  |  |  | 	return add2(x, 1) // ERROR "inlining call to add2" "inlining call to add1" | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-08-24 19:45:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | //go:noinline | 
					
						
							|  |  |  | func g(x int) int { | 
					
						
							|  |  |  | 	return x + 1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func h(x int) int { // ERROR "can inline h" | 
					
						
							|  |  |  | 	return x + 2 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-16 18:44:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | func i(x int) int { // ERROR "can inline i" | 
					
						
							|  |  |  | 	const y = 2 | 
					
						
							|  |  |  | 	return x + y | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-16 21:29:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | func j(x int) int { // ERROR "can inline j" | 
					
						
							|  |  |  | 	switch { | 
					
						
							|  |  |  | 	case x > 0: | 
					
						
							|  |  |  | 		return x + 2 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return x + 1 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-22 02:19:14 -07:00
										 |  |  | func _() int { // ERROR "can inline _" | 
					
						
							|  |  |  | 	tmp1 := h | 
					
						
							|  |  |  | 	tmp2 := tmp1 | 
					
						
							|  |  |  | 	return tmp2(0) // ERROR "inlining call to h" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 19:24:55 -07:00
										 |  |  | var somethingWrong error | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // local closures can be inlined | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | func l(x, y int) (int, int, error) { // ERROR "can inline l" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 	e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result" | 
					
						
							|  |  |  | 		return 0, 0, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if x == y { | 
					
						
							|  |  |  | 		e(somethingWrong) // ERROR "inlining call to l.func1" | 
					
						
							| 
									
										
										
										
											2020-09-22 02:19:14 -07:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		f := e | 
					
						
							|  |  |  | 		f(nil) // ERROR "inlining call to l.func1" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return y, x, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // any re-assignment prevents closure inlining | 
					
						
							|  |  |  | func m() int { | 
					
						
							|  |  |  | 	foo := func() int { return 1 } // ERROR "can inline m.func1" "func literal does not escape" | 
					
						
							|  |  |  | 	x := foo() | 
					
						
							|  |  |  | 	foo = func() int { return 2 } // ERROR "can inline m.func2" "func literal does not escape" | 
					
						
							|  |  |  | 	return x + foo() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // address taking prevents closure inlining | 
					
						
							|  |  |  | func n() int { | 
					
						
							|  |  |  | 	foo := func() int { return 1 } // ERROR "can inline n.func1" "func literal does not escape" | 
					
						
							| 
									
										
										
										
											2019-04-01 11:58:33 -07:00
										 |  |  | 	bar := &foo | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 	x := (*bar)() + foo() | 
					
						
							|  |  |  | 	return x | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // make sure assignment inside closure is detected | 
					
						
							|  |  |  | func o() int { | 
					
						
							|  |  |  | 	foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape" | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | 	func(x int) {                  // ERROR "can inline o.func2" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 		if x > 10 { | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | 			foo = func() int { return 2 } // ERROR "can inline o.func2" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 		} | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | 	}(11) // ERROR "func literal does not escape" "inlining call to o.func2" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 	return foo() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | func p() int { // ERROR "can inline p" | 
					
						
							| 
									
										
										
										
											2017-09-18 14:54:10 -07:00
										 |  |  | 	return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | func q(x int) int { // ERROR "can inline q" | 
					
						
							| 
									
										
										
										
											2019-09-12 10:18:03 -07:00
										 |  |  | 	foo := func() int { return x * 2 } // ERROR "can inline q.func1" "func literal does not escape" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | 	return foo()                       // ERROR "inlining call to q.func1" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func r(z int) int { | 
					
						
							| 
									
										
										
										
											2019-09-12 10:18:03 -07:00
										 |  |  | 	foo := func(x int) int { // ERROR "can inline r.func1" "func literal does not escape" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | 		return x + z | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | 	bar := func(x int) int { // ERROR "func literal does not escape" "can inline r.func2" | 
					
						
							|  |  |  | 		return x + func(y int) int { // ERROR "can inline r.func2.1" "can inline r.func3" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | 			return 2*y + x*z | 
					
						
							|  |  |  | 		}(x) // ERROR "inlining call to r.func2.1" | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | 	return foo(42) + bar(42) // ERROR "inlining call to r.func1" "inlining call to r.func2" "inlining call to r.func3" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | func s0(x int) int { // ERROR "can inline s0" | 
					
						
							| 
									
										
										
										
											2019-09-12 10:18:03 -07:00
										 |  |  | 	foo := func() { // ERROR "can inline s0.func1" "func literal does not escape" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | 		x = x + 1 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-01 11:58:33 -07:00
										 |  |  | 	foo() // ERROR "inlining call to s0.func1" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | 	return x | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
  - Write out the Func type, Dcls, ClosureVars, and Body when exporting
    an OCLOSURE.
  - When importing an OCLOSURE, read in the type, dcls, closure vars,
    and body, and then do roughly equivalent code to (*noder).funcLit
  - During inlining of a closure within inlined function, create new
    nodes for all params and local variables (including closure
    variables), so they can have a new Curfn and some other field
    values. Must substitute not only on the Nbody of the closure, but
    also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
											
										 
											2020-12-01 14:48:03 -08:00
										 |  |  | func s1(x int) int { // ERROR "can inline s1" | 
					
						
							| 
									
										
										
										
											2019-09-12 10:18:03 -07:00
										 |  |  | 	foo := func() int { // ERROR "can inline s1.func1" "func literal does not escape" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | 		return x | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	x = x + 1 | 
					
						
							| 
									
										
										
										
											2019-04-01 11:58:33 -07:00
										 |  |  | 	return foo() // ERROR "inlining call to s1.func1" | 
					
						
							| 
									
										
										
										
											2017-10-21 15:58:37 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 21:29:17 -05:00
										 |  |  | // can't currently inline functions with a break statement | 
					
						
							|  |  |  | func switchBreak(x, y int) int { | 
					
						
							|  |  |  | 	var n int | 
					
						
							|  |  |  | 	switch x { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							|  |  |  | 		n = 1 | 
					
						
							|  |  |  | 	Done: | 
					
						
							|  |  |  | 		switch y { | 
					
						
							|  |  |  | 		case 0: | 
					
						
							|  |  |  | 			n += 10 | 
					
						
							|  |  |  | 			break Done | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		n = 2 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return n | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 01:13:16 -07:00
										 |  |  | func switchType(x interface{}) int { // ERROR "can inline switchType" "x does not escape" | 
					
						
							| 
									
										
										
										
											2016-03-16 21:29:17 -05:00
										 |  |  | 	switch x.(type) { | 
					
						
							|  |  |  | 	case int: | 
					
						
							|  |  |  | 		return x.(int) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-10-10 09:35:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | type T struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (T) meth(int, int) {} // ERROR "can inline T.meth" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func k() (T, int, int) { return T{}, 0, 0 } // ERROR "can inline k" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _() { // ERROR "can inline _" | 
					
						
							|  |  |  | 	T.meth(k()) // ERROR "inlining call to k" "inlining call to T.meth" | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-11-04 19:23:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func small1() { // ERROR "can inline small1" | 
					
						
							|  |  |  | 	runtime.GC() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func small2() int { // ERROR "can inline small2" | 
					
						
							|  |  |  | 	return runtime.GOMAXPROCS(0) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func small3(t T) { // ERROR "can inline small3" | 
					
						
							|  |  |  | 	t.meth2(3, 5) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func small4(t T) { // not inlineable - has 2 calls. | 
					
						
							|  |  |  | 	t.meth2(runtime.GOMAXPROCS(0), 5) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func (T) meth2(int, int) { // not inlineable - has 2 calls. | 
					
						
							|  |  |  | 	runtime.GC() | 
					
						
							|  |  |  | 	runtime.GC() | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-31 20:24:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Issue #29737 - make sure we can do inlining for a chain of recursive functions | 
					
						
							|  |  |  | func ee() { // ERROR "can inline ee" | 
					
						
							|  |  |  | 	ff(100) // ERROR "inlining call to ff" "inlining call to gg" "inlining call to hh" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func ff(x int) { // ERROR "can inline ff" | 
					
						
							|  |  |  | 	if x < 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	gg(x - 1) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func gg(x int) { // ERROR "can inline gg" | 
					
						
							|  |  |  | 	hh(x - 1) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func hh(x int) { // ERROR "can inline hh" | 
					
						
							|  |  |  | 	ff(x - 1) // ERROR "inlining call to ff"  // ERROR "inlining call to gg" | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-09-21 20:20:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Issue #14768 - make sure we can inline for loops. | 
					
						
							|  |  |  | func for1(fn func() bool) { // ERROR "can inline for1" "fn does not escape" | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		if fn() { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // BAD: for2 should be inlineable too. | 
					
						
							|  |  |  | func for2(fn func() bool) { // ERROR "fn does not escape" | 
					
						
							|  |  |  | Loop: | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		if fn() { | 
					
						
							|  |  |  | 			break Loop | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			continue Loop | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-19 13:09:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Issue #18493 - make sure we can do inlining of functions with a method value | 
					
						
							|  |  |  | type T1 struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (a T1) meth(val int) int { // ERROR "can inline T1.meth" "inlining call to T1.meth" | 
					
						
							|  |  |  | 	return val + 5 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func getMeth(t1 T1) func(int) int { // ERROR "can inline getMeth" | 
					
						
							|  |  |  | 	return t1.meth // ERROR "t1.meth escapes to heap" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func ii() { // ERROR "can inline ii" | 
					
						
							|  |  |  | 	var t1 T1 | 
					
						
							|  |  |  | 	f := getMeth(t1) // ERROR "inlining call to getMeth" "t1.meth does not escape" | 
					
						
							|  |  |  | 	_ = f(3) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-25 14:26:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Issue #42194 - make sure that functions evaluated in | 
					
						
							|  |  |  | // go and defer statements can be inlined. | 
					
						
							|  |  |  | func gd1(int) { | 
					
						
							|  |  |  | 	defer gd1(gd2()) // ERROR "inlining call to gd2" | 
					
						
							|  |  |  | 	defer gd3()()    // ERROR "inlining call to gd3" | 
					
						
							|  |  |  | 	go gd1(gd2())    // ERROR "inlining call to gd2" | 
					
						
							|  |  |  | 	go gd3()()       // ERROR "inlining call to gd3" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func gd2() int { // ERROR "can inline gd2" | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func gd3() func() { // ERROR "can inline gd3" | 
					
						
							|  |  |  | 	return ii | 
					
						
							|  |  |  | } |