]> Cypherpunks.ru repositories - gostls13.git/blob - test/fixedbugs/issue16249.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / fixedbugs / issue16249.go
1 // run
2
3 // Copyright 2016 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 // Liveness calculations were wrong for a result parameter pushed onto
8 // the heap in a function that used defer.  Program would crash with
9 //     runtime: bad pointer in frame main.A at 0xc4201e6838: 0x1
10
11 package main
12
13 import "errors"
14
15 var sink interface{}
16
17 //go:noinline
18 func f(err *error) {
19         if err != nil {
20                 sink = err
21         }
22 }
23
24 //go:noinline
25 func A(n, m int64) (res int64, err error) {
26         defer f(&err) // output parameter's address escapes to a defer.
27         if n < 0 {
28                 err = errors.New("No negative")
29                 return
30         }
31         if n <= 1 {
32                 res = n
33                 return
34         }
35         res = B(m) // This call to B drizzles a little junk on the stack.
36         res, err = A(n-1, m)
37         res++
38         return
39 }
40
41 // B does a little bit of recursion dribbling not-zero onto the stack.
42 //go:noinline
43 func B(n int64) (res int64) {
44         if n <= 1 { // Prefer to leave a 1 on the stack.
45                 return n
46         }
47         return 1 + B(n-1)
48 }
49
50 func main() {
51         x, e := A(0, 0)
52         for j := 0; j < 4; j++ { // j controls amount of B's stack dribble
53                 for i := 0; i < 1000; i++ { // try more and more recursion until stack growth occurs in newobject in prologue
54                         x, e = A(int64(i), int64(j))
55                 }
56         }
57         _, _ = x, e
58 }