]> Cypherpunks.ru repositories - gostls13.git/blob - test/fixedbugs/issue8048.go
a7984c45a3989104796c5dc0144b5c382dbb520e
[gostls13.git] / test / fixedbugs / issue8048.go
1 // run
2
3 // Copyright 2014 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 8048. Incorrect handling of liveness when walking stack
8 // containing faulting frame.
9
10 package main
11
12 import "runtime"
13
14 func main() {
15         test1()
16         test2()
17         test3()
18 }
19
20 func test1() {
21         // test1f will panic without its own defer.
22         // The runtime.GC checks that we can walk the stack
23         // at that point and not get confused.
24         // The recover lets test1 exit normally.
25         defer func() {
26                 runtime.GC()
27                 recover()
28         }()
29         test1f()
30 }
31
32 func test1f() {
33         // Because b == false, the if does not execute,
34         // so x == nil, so the println(*x) faults reading
35         // from nil. The compiler will lay out the code
36         // so that the if body occurs above the *x,
37         // so if the liveness info at the *x is used, it will
38         // find the liveness at the call to runtime.GC.
39         // It will think y is live, but y is uninitialized,
40         // and the runtime will crash detecting a bad slice.
41         // The runtime should see that there are no defers
42         // corresponding to this panicked frame and ignore
43         // the frame entirely.
44         var x *int
45         var b bool
46         if b {
47                 y := make([]int, 1)
48                 runtime.GC()
49                 x = &y[0]
50         }
51         println(*x)
52 }
53
54 func test2() {
55         // Same as test1, but the fault happens in the function with the defer.
56         // The runtime should see the defer and garbage collect the frame
57         // as if the PC were immediately after the defer statement.
58         defer func() {
59                 runtime.GC()
60                 recover()
61         }()
62         var x *int
63         var b bool
64         if b {
65                 y := make([]int, 1)
66                 runtime.GC()
67                 x = &y[0]
68         }
69         println(*x)
70 }
71
72 func test3() {
73         // Like test1 but avoid array index, which does not
74         // move to end of function on ARM.
75         defer func() {
76                 runtime.GC()
77                 recover()
78         }()
79         test3setup()
80         test3f()
81 }
82
83 func test3setup() {
84         var x uintptr
85         var b bool
86         b = true
87         if b {
88                 y := uintptr(123)
89                 runtime.GC()
90                 x = y
91         }
92         runtime.GC()
93         globl = x
94 }
95
96 var globl uintptr
97
98 func test3f() {
99         var x *int
100         var b bool
101         if b {
102                 y := new(int)
103                 runtime.GC()
104                 x = y
105         }
106         println(*x)
107 }