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

     1  # Test closure naming with inlining.
     2  
     3  go build -gcflags=-S -o x.exe x.go
     4  # original closure name should appear
     5  stderr '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
    16  stderr 'ranger\.func1'
    17  stderr 'ranger-range1'
    18  stderr 'ranger\.func2'
    19  
    20  go tool nm x.exe
    21  # same applies to the nm output
    22  stdout 'adder\.func1'
    23  ! stdout 'F1\.adder\.func1'
    24  ! stdout 'F2\.adder\.func1'
    25  ! stdout 'adder\.func2'
    26  ! stdout 'adder\.func3'
    27  ! stdout 'adder\.func4'
    28  stdout 'ranger\.func1'
    29  stdout 'ranger-range1'
    30  stdout 'ranger\.func2'
    31  # the inline hash should not make into the final binary
    32  ! stdout 'adder\.func1#'
    33  
    34  -- x.go --
    35  package main
    36  
    37  // keep prevents closures being optimized out
    38  //
    39  //go:noinline
    40  func keep(x func()) func() { return x }
    41  
    42  func adder(n int) func(int) int {
    43  	return func(x int) int { return x + n }
    44  }
    45  
    46  //go:noinline
    47  func 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
    54  func 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
    64  func iter(yield func(int) bool) {
    65  	_ = yield(1) && yield(2) && yield(3)
    66  }
    67  
    68  func 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  
    77  func main() {
    78  	x := 1
    79  	F1()(F2()(ranger()(x)))
    80  }
    81  

View as plain text