blob: 0ec1c8d9dece272c8df616fc3745fc5039fac4e0 [file]
# 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)))
}