Home | History | Annotate | Download | only in fixedbugs
      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 }
     50