blob: b784914e590af5124570bb5f53f6f85fa4e15b0d [file] [log] [blame]
Russ Cox57eb06f2012-02-16 23:51:04 -05001// run
Russ Cox67d48da2011-09-26 13:59:01 -04002
Russ Cox4bdf1fc2011-09-26 19:35:21 -04003// Copyright 2011 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 Pike19bab1d2012-02-24 10:30:39 +11007// Test that the implementation catches nil ptr indirection
8// in a large address space.
9
Russ Cox67d48da2011-09-26 13:59:01 -040010package main
11
12import "unsafe"
13
14// Having a big address space means that indexing
15// at a 256 MB offset from a nil pointer might not
16// cause a memory access fault. This test checks
17// that Go is doing the correct explicit checks to catch
18// these nil pointer accesses, not just relying on the hardware.
Russ Cox3c56a7b2011-12-07 15:00:44 -050019var dummy [256 << 20]byte // give us a big address space
Russ Cox67d48da2011-09-26 13:59:01 -040020
21func main() {
22 // the test only tests what we intend to test
23 // if dummy starts in the first 256 MB of memory.
24 // otherwise there might not be anything mapped
25 // at the address that might be accidentally
26 // dereferenced below.
27 if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
28 panic("dummy too far out")
29 }
30
31 shouldPanic(p1)
32 shouldPanic(p2)
33 shouldPanic(p3)
34 shouldPanic(p4)
35 shouldPanic(p5)
36 shouldPanic(p6)
37 shouldPanic(p7)
38 shouldPanic(p8)
39 shouldPanic(p9)
40 shouldPanic(p10)
41}
42
43func shouldPanic(f func()) {
44 defer func() {
45 if recover() == nil {
46 panic("memory reference did not panic")
47 }
48 }()
49 f()
50}
51
52func p1() {
53 // Array index.
54 var p *[1 << 30]byte = nil
55 println(p[256<<20]) // very likely to be inside dummy, but should panic
56}
57
58var xb byte
59
60func p2() {
61 var p *[1 << 30]byte = nil
62 xb = 123
63
64 // Array index.
65 println(p[uintptr(unsafe.Pointer(&xb))]) // should panic
66}
67
68func p3() {
69 // Array to slice.
70 var p *[1 << 30]byte = nil
71 var x []byte = p[0:] // should panic
72 _ = x
73}
74
75var q *[1 << 30]byte
76
77func p4() {
78 // Array to slice.
79 var x []byte
80 var y = &x
81 *y = q[0:] // should crash (uses arraytoslice runtime routine)
82}
83
84func fb([]byte) {
85 panic("unreachable")
86}
87
88func p5() {
89 // Array to slice.
90 var p *[1 << 30]byte = nil
91 fb(p[0:]) // should crash
92}
93
94func p6() {
95 // Array to slice.
96 var p *[1 << 30]byte = nil
97 var _ []byte = p[10 : len(p)-10] // should crash
98}
99
100type T struct {
101 x [256 << 20]byte
102 i int
103}
104
105func f() *T {
106 return nil
107}
108
109var y *T
110var x = &y
111
112func p7() {
113 // Struct field access with large offset.
114 println(f().i) // should crash
115}
116
117func p8() {
118 // Struct field access with large offset.
119 println((*x).i) // should crash
120}
121
122func p9() {
123 // Struct field access with large offset.
124 var t *T
125 println(&t.i) // should crash
126}
127
128func p10() {
129 // Struct field access with large offset.
130 var t *T
131 println(t.i) // should crash
132}