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