modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/fixedbugs/issue10353.go (about)

     1  // run
     2  
     3  // Copyright 2015 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // issue 10253: cmd/gc: incorrect escape analysis of closures
     8  // Partial call x.foo was not promoted to heap.
     9  
    10  package main
    11  
    12  func main() {
    13  	c := make(chan bool)
    14  	// Create a new goroutine to get a default-size stack segment.
    15  	go func() {
    16  		x := new(X)
    17  		clos(x.foo)()
    18  		c <- true
    19  	}()
    20  	<-c
    21  }
    22  
    23  type X int
    24  
    25  func (x *X) foo() {
    26  }
    27  
    28  func clos(x func()) func() {
    29  	f := func() {
    30  		print("")
    31  		x() // This statement crashed, because the partial call was allocated on the old stack.
    32  	}
    33  	// Grow stack so that partial call x becomes invalid if allocated on stack.
    34  	growstack(10000)
    35  	c := make(chan bool)
    36  	// Spoil the previous stack segment.
    37  	go func() {
    38  		c <- true
    39  	}()
    40  	<-c
    41  	return f
    42  }
    43  
    44  func growstack(x int) {
    45  	if x == 0 {
    46  		return
    47  	}
    48  	growstack(x - 1)
    49  }