Russ Cox | 57eb06f | 2012-02-16 23:51:04 -0500 | [diff] [blame] | 1 | // run |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 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 | |
Rob Pike | 19bab1d | 2012-02-24 10:30:39 +1100 | [diff] [blame] | 7 | // Test recovering from runtime errors. |
| 8 | |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 9 | package main |
| 10 | |
| 11 | import ( |
| 12 | "runtime" |
| 13 | "strings" |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 14 | ) |
| 15 | |
| 16 | var didbug bool |
| 17 | |
| 18 | func bug() { |
| 19 | if didbug { |
| 20 | return |
| 21 | } |
| 22 | println("BUG") |
| 23 | didbug = true |
| 24 | } |
| 25 | |
| 26 | func check(name string, f func(), err string) { |
| 27 | defer func() { |
| 28 | v := recover() |
| 29 | if v == nil { |
| 30 | bug() |
| 31 | println(name, "did not panic") |
| 32 | return |
| 33 | } |
| 34 | runt, ok := v.(runtime.Error) |
| 35 | if !ok { |
| 36 | bug() |
| 37 | println(name, "panicked but not with runtime.Error") |
| 38 | return |
| 39 | } |
Russ Cox | 44526cd | 2011-11-01 22:06:05 -0400 | [diff] [blame] | 40 | s := runt.Error() |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 41 | if strings.Index(s, err) < 0 { |
| 42 | bug() |
| 43 | println(name, "panicked with", s, "not", err) |
| 44 | return |
| 45 | } |
| 46 | }() |
Russ Cox | 8fff916 | 2010-10-25 21:25:13 -0700 | [diff] [blame] | 47 | |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 48 | f() |
| 49 | } |
| 50 | |
| 51 | func main() { |
| 52 | var x int |
| 53 | var x64 int64 |
| 54 | var p *[10]int |
| 55 | var q *[10000]int |
| 56 | var i int |
| 57 | |
Russ Cox | 8fff916 | 2010-10-25 21:25:13 -0700 | [diff] [blame] | 58 | check("int-div-zero", func() { println(1 / x) }, "integer divide by zero") |
| 59 | check("int64-div-zero", func() { println(1 / x64) }, "integer divide by zero") |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 60 | |
| 61 | check("nil-deref", func() { println(p[0]) }, "nil pointer dereference") |
| 62 | check("nil-deref-1", func() { println(p[1]) }, "nil pointer dereference") |
| 63 | check("nil-deref-big", func() { println(q[5000]) }, "nil pointer dereference") |
| 64 | |
| 65 | i = 99999 |
| 66 | var sl []int |
Russ Cox | 08fdf00 | 2013-08-15 11:51:04 -0400 | [diff] [blame] | 67 | p1 := new([10]int) |
| 68 | check("array-bounds", func() { println(p1[i]) }, "index out of range") |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 69 | check("slice-bounds", func() { println(sl[i]) }, "index out of range") |
Russ Cox | 8fff916 | 2010-10-25 21:25:13 -0700 | [diff] [blame] | 70 | |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 71 | var inter interface{} |
| 72 | inter = 1 |
| 73 | check("type-concrete", func() { println(inter.(string)) }, "int, not string") |
| 74 | check("type-interface", func() { println(inter.(m)) }, "missing method m") |
Alan Donovan | 052c942 | 2013-02-12 13:17:49 -0500 | [diff] [blame] | 75 | |
| 76 | if didbug { |
| 77 | panic("recover3") |
| 78 | } |
Russ Cox | 5963dba | 2010-04-08 18:15:30 -0700 | [diff] [blame] | 79 | } |
| 80 | |
Russ Cox | 8fff916 | 2010-10-25 21:25:13 -0700 | [diff] [blame] | 81 | type m interface { |
| 82 | m() |
| 83 | } |