| 
									
										
										
										
											2012-02-16 23:51:04 -05:00
										 |  |  | // run | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 14:32:26 -07:00
										 |  |  | // Copyright 2010 The Go Authors. All rights reserved. | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-24 10:30:39 +11:00
										 |  |  | // Test recovering from runtime errors. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var didbug bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func bug() { | 
					
						
							|  |  |  | 	if didbug { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	println("BUG") | 
					
						
							|  |  |  | 	didbug = true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check(name string, f func(), err string) { | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		v := recover() | 
					
						
							|  |  |  | 		if v == nil { | 
					
						
							|  |  |  | 			bug() | 
					
						
							|  |  |  | 			println(name, "did not panic") | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		runt, ok := v.(runtime.Error) | 
					
						
							|  |  |  | 		if !ok { | 
					
						
							|  |  |  | 			bug() | 
					
						
							|  |  |  | 			println(name, "panicked but not with runtime.Error") | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-11-01 22:06:05 -04:00
										 |  |  | 		s := runt.Error() | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | 		if strings.Index(s, err) < 0 { | 
					
						
							|  |  |  | 			bug() | 
					
						
							|  |  |  | 			println(name, "panicked with", s, "not", err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2010-10-25 21:25:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | 	f() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func main() { | 
					
						
							|  |  |  | 	var x int | 
					
						
							|  |  |  | 	var x64 int64 | 
					
						
							|  |  |  | 	var p *[10]int | 
					
						
							|  |  |  | 	var q *[10000]int | 
					
						
							|  |  |  | 	var i int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-25 21:25:13 -07:00
										 |  |  | 	check("int-div-zero", func() { println(1 / x) }, "integer divide by zero") | 
					
						
							|  |  |  | 	check("int64-div-zero", func() { println(1 / x64) }, "integer divide by zero") | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	check("nil-deref", func() { println(p[0]) }, "nil pointer dereference") | 
					
						
							|  |  |  | 	check("nil-deref-1", func() { println(p[1]) }, "nil pointer dereference") | 
					
						
							|  |  |  | 	check("nil-deref-big", func() { println(q[5000]) }, "nil pointer dereference") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	i = 99999 | 
					
						
							|  |  |  | 	var sl []int | 
					
						
							| 
									
										
										
										
											2013-08-15 11:51:04 -04:00
										 |  |  | 	p1 := new([10]int) | 
					
						
							|  |  |  | 	check("array-bounds", func() { println(p1[i]) }, "index out of range") | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | 	check("slice-bounds", func() { println(sl[i]) }, "index out of range") | 
					
						
							| 
									
										
										
										
											2010-10-25 21:25:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | 	var inter interface{} | 
					
						
							|  |  |  | 	inter = 1 | 
					
						
							|  |  |  | 	check("type-concrete", func() { println(inter.(string)) }, "int, not string") | 
					
						
							|  |  |  | 	check("type-interface", func() { println(inter.(m)) }, "missing method m") | 
					
						
							| 
									
										
										
										
											2013-02-12 13:17:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if didbug { | 
					
						
							|  |  |  | 		panic("recover3") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-08 18:15:30 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-25 21:25:13 -07:00
										 |  |  | type m interface { | 
					
						
							|  |  |  | 	m() | 
					
						
							|  |  |  | } |