...

Text file src/cmd/compile/testdata/script/closure_name.txt

Documentation: cmd/compile/testdata/script

     1# Test closure naming with inlining.
     2
     3go build -gcflags=-S -o x.exe x.go
     4# original closure name should appear
     5stderr 'adder\.func1'
     6# inlining should not cause the closure to have longer names
     7! stderr 'F1\.adder\.func1'
     8! stderr 'F2\.adder\.func1'
     9# the counter should match the original one, regardless of
    10# how many closures are in the inlined caller
    11! stderr 'adder\.func2'
    12! stderr 'adder\.func3'
    13! stderr 'adder\.func4'
    14# user closure counter and range func counter should not
    15# interfere
    16stderr 'ranger\.func1'
    17stderr 'ranger-range1'
    18stderr 'ranger\.func2'
    19
    20go tool nm x.exe
    21# same applies to the nm output
    22stdout 'adder\.func1'
    23! stdout 'F1\.adder\.func1'
    24! stdout 'F2\.adder\.func1'
    25! stdout 'adder\.func2'
    26! stdout 'adder\.func3'
    27! stdout 'adder\.func4'
    28stdout 'ranger\.func1'
    29stdout 'ranger-range1'
    30stdout 'ranger\.func2'
    31# the inline hash should not make into the final binary
    32! stdout 'adder\.func1#'
    33
    34-- x.go --
    35package main
    36
    37// keep prevents closures being optimized out
    38//
    39//go:noinline
    40func keep(x func()) func() { return x }
    41
    42func adder(n int) func(int) int {
    43	return func(x int) int { return x + n }
    44}
    45
    46//go:noinline
    47func F1() func(int) int {
    48	// adder is inlined into F1, along with its closure.
    49	// The closure should still be named addr.func1.
    50	return adder(1)
    51}
    52
    53//go:noinline
    54func F2() func(int) int {
    55	keep(func() {})
    56	keep(func() {})
    57	keep(func() {})
    58	// Closures in the outer function should not change
    59	// the counter. It should still be addr.func1.
    60	return adder(2)
    61}
    62
    63//go:noinline
    64func iter(yield func(int) bool) {
    65	_ = yield(1) && yield(2) && yield(3)
    66}
    67
    68func ranger() func(int) int {
    69	keep(func() {}) // func1
    70	s := 0
    71	for x := range iter { // range1
    72		s += x
    73	}
    74	return func(x int) int { return s + x } // func2
    75}
    76
    77func main() {
    78	x := 1
    79	F1()(F2()(ranger()(x)))
    80}

View as plain text