OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [recover.go] - Blame information for rev 700

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 700 jeremybenn
// $G $D/$F.go && $L $F.$A && ./$A.out
2
 
3
// Copyright 2010 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
// Test of basic recover functionality.
8
 
9
package main
10
 
11
import "runtime"
12
 
13
func main() {
14
        test1()
15
        test1WithClosures()
16
        test2()
17
        test3()
18
        test4()
19
        test5()
20
        test6()
21
        test6WithClosures()
22
        test7()
23
}
24
 
25
func die() {
26
        runtime.Breakpoint() // can't depend on panic
27
}
28
 
29
func mustRecover(x interface{}) {
30
        mustNotRecover() // because it's not a defer call
31
        v := recover()
32
        if v == nil {
33
                println("missing recover")
34
                die() // panic is useless here
35
        }
36
        if v != x {
37
                println("wrong value", v, x)
38
                die()
39
        }
40
 
41
        // the value should be gone now regardless
42
        v = recover()
43
        if v != nil {
44
                println("recover didn't recover")
45
                die()
46
        }
47
}
48
 
49
func mustNotRecover() {
50
        v := recover()
51
        if v != nil {
52
                println("spurious recover", v)
53
                die()
54
        }
55
}
56
 
57
func withoutRecover() {
58
        mustNotRecover() // because it's a sub-call
59
}
60
 
61
func test1() {
62
        defer mustNotRecover() // because mustRecover will squelch it
63
        defer mustRecover(1)   // because of panic below
64
        defer withoutRecover() // should be no-op, leaving for mustRecover to find
65
        panic(1)
66
}
67
 
68
// Repeat test1 with closures instead of standard function.
69
// Interesting because recover bases its decision
70
// on the frame pointer of its caller, and a closure's
71
// frame pointer is in the middle of its actual arguments
72
// (after the hidden ones for the closed-over variables).
73
func test1WithClosures() {
74
        defer func() {
75
                v := recover()
76
                if v != nil {
77
                        println("spurious recover in closure")
78
                        die()
79
                }
80
        }()
81
        defer func(x interface{}) {
82
                mustNotRecover()
83
                v := recover()
84
                if v == nil {
85
                        println("missing recover")
86
                        die()
87
                }
88
                if v != x {
89
                        println("wrong value", v, x)
90
                        die()
91
                }
92
        }(1)
93
        defer func() {
94
                mustNotRecover()
95
        }()
96
        panic(1)
97
}
98
 
99
func test2() {
100
        // Recover only sees the panic argument
101
        // if it is called from a deferred call.
102
        // It does not see the panic when called from a call within a deferred call (too late)
103
        // nor does it see the panic when it *is* the deferred call (too early).
104
        defer mustRecover(2)
105
        defer recover() // should be no-op
106
        panic(2)
107
}
108
 
109
func test3() {
110
        defer mustNotRecover()
111
        defer func() {
112
                recover() // should squelch
113
        }()
114
        panic(3)
115
}
116
 
117
func test4() {
118
        // Equivalent to test3 but using defer to make the call.
119
        defer mustNotRecover()
120
        defer func() {
121
                defer recover() // should squelch
122
        }()
123
        panic(4)
124
}
125
 
126
// Check that closures can set output arguments.
127
// Run g().  If it panics, return x; else return deflt.
128
func try(g func(), deflt interface{}) (x interface{}) {
129
        defer func() {
130
                if v := recover(); v != nil {
131
                        x = v
132
                }
133
        }()
134
        defer g()
135
        return deflt
136
}
137
 
138
// Check that closures can set output arguments.
139
// Run g().  If it panics, return x; else return deflt.
140
func try1(g func(), deflt interface{}) (x interface{}) {
141
        defer func() {
142
                if v := recover(); v != nil {
143
                        x = v
144
                }
145
        }()
146
        defer g()
147
        x = deflt
148
        return
149
}
150
 
151
func test5() {
152
        v := try(func() { panic(5) }, 55).(int)
153
        if v != 5 {
154
                println("wrong value", v, 5)
155
                die()
156
        }
157
 
158
        s := try(func() {}, "hi").(string)
159
        if s != "hi" {
160
                println("wrong value", s, "hi")
161
                die()
162
        }
163
 
164
        v = try1(func() { panic(5) }, 55).(int)
165
        if v != 5 {
166
                println("try1 wrong value", v, 5)
167
                die()
168
        }
169
 
170
        s = try1(func() {}, "hi").(string)
171
        if s != "hi" {
172
                println("try1 wrong value", s, "hi")
173
                die()
174
        }
175
}
176
 
177
// When a deferred big call starts, it must first
178
// create yet another stack segment to hold the
179
// giant frame for x.  Make sure that doesn't
180
// confuse recover.
181
func big(mustRecover bool) {
182
        var x [100000]int
183
        x[0] = 1
184
        x[99999] = 1
185
        _ = x
186
 
187
        v := recover()
188
        if mustRecover {
189
                if v == nil {
190
                        println("missing big recover")
191
                        die()
192
                }
193
        } else {
194
                if v != nil {
195
                        println("spurious big recover")
196
                        die()
197
                }
198
        }
199
}
200
 
201
func test6() {
202
        defer big(false)
203
        defer big(true)
204
        panic(6)
205
}
206
 
207
func test6WithClosures() {
208
        defer func() {
209
                var x [100000]int
210
                x[0] = 1
211
                x[99999] = 1
212
                _ = x
213
                if recover() != nil {
214
                        println("spurious big closure recover")
215
                        die()
216
                }
217
        }()
218
        defer func() {
219
                var x [100000]int
220
                x[0] = 1
221
                x[99999] = 1
222
                _ = x
223
                if recover() == nil {
224
                        println("missing big closure recover")
225
                        die()
226
                }
227
        }()
228
        panic("6WithClosures")
229
}
230
 
231
func test7() {
232
        ok := false
233
        func() {
234
                // should panic, then call mustRecover 7, which stops the panic.
235
                // then should keep processing ordinary defers earlier than that one
236
                // before returning.
237
                // this test checks that the defer func on the next line actually runs.
238
                defer func() { ok = true }()
239
                defer mustRecover(7)
240
                panic(7)
241
        }()
242
        if !ok {
243
                println("did not run ok func")
244
                die()
245
        }
246
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.