| # Test closure naming with inlining. |
| |
| go build -gcflags=-S -o x.exe x.go |
| # original closure name should appear |
| stderr 'adder\.func1' |
| # inlining should not cause the closure to have longer names |
| ! stderr 'F1\.adder\.func1' |
| ! stderr 'F2\.adder\.func1' |
| # the counter should match the original one, regardless of |
| # how many closures are in the inlined caller |
| ! stderr 'adder\.func2' |
| ! stderr 'adder\.func3' |
| ! stderr 'adder\.func4' |
| # user closure counter and range func counter should not |
| # interfere |
| stderr 'ranger\.func1' |
| stderr 'ranger-range1' |
| stderr 'ranger\.func2' |
| |
| go tool nm x.exe |
| # same applies to the nm output |
| stdout 'adder\.func1' |
| ! stdout 'F1\.adder\.func1' |
| ! stdout 'F2\.adder\.func1' |
| ! stdout 'adder\.func2' |
| ! stdout 'adder\.func3' |
| ! stdout 'adder\.func4' |
| stdout 'ranger\.func1' |
| stdout 'ranger-range1' |
| stdout 'ranger\.func2' |
| # the inline hash should not make into the final binary |
| ! stdout 'adder\.func1#' |
| |
| -- x.go -- |
| package main |
| |
| // keep prevents closures being optimized out |
| // |
| //go:noinline |
| func keep(x func()) func() { return x } |
| |
| func adder(n int) func(int) int { |
| return func(x int) int { return x + n } |
| } |
| |
| //go:noinline |
| func F1() func(int) int { |
| // adder is inlined into F1, along with its closure. |
| // The closure should still be named addr.func1. |
| return adder(1) |
| } |
| |
| //go:noinline |
| func F2() func(int) int { |
| keep(func() {}) |
| keep(func() {}) |
| keep(func() {}) |
| // Closures in the outer function should not change |
| // the counter. It should still be addr.func1. |
| return adder(2) |
| } |
| |
| //go:noinline |
| func iter(yield func(int) bool) { |
| _ = yield(1) && yield(2) && yield(3) |
| } |
| |
| func ranger() func(int) int { |
| keep(func() {}) // func1 |
| s := 0 |
| for x := range iter { // range1 |
| s += x |
| } |
| return func(x int) int { return s + x } // func2 |
| } |
| |
| func main() { |
| x := 1 |
| F1()(F2()(ranger()(x))) |
| } |