blob: 9631d1618b5a07cddee9e13ae7582f69e0de2eed [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)
Ian Lance Taylor578dc3a2013-04-24 08:13:01 -070041 shouldPanic(p11)
42 shouldPanic(p12)
Russ Cox1116f74e2013-09-05 23:06:34 -040043 shouldPanic(p13)
44 shouldPanic(p14)
45 shouldPanic(p15)
46 shouldPanic(p16)
Russ Cox67d48da2011-09-26 13:59:01 -040047}
48
49func shouldPanic(f func()) {
50 defer func() {
51 if recover() == nil {
52 panic("memory reference did not panic")
53 }
54 }()
55 f()
56}
57
58func p1() {
59 // Array index.
60 var p *[1 << 30]byte = nil
61 println(p[256<<20]) // very likely to be inside dummy, but should panic
62}
63
64var xb byte
65
66func p2() {
67 var p *[1 << 30]byte = nil
68 xb = 123
69
70 // Array index.
71 println(p[uintptr(unsafe.Pointer(&xb))]) // should panic
72}
73
74func p3() {
75 // Array to slice.
76 var p *[1 << 30]byte = nil
77 var x []byte = p[0:] // should panic
78 _ = x
79}
80
81var q *[1 << 30]byte
82
83func p4() {
84 // Array to slice.
85 var x []byte
86 var y = &x
87 *y = q[0:] // should crash (uses arraytoslice runtime routine)
88}
89
90func fb([]byte) {
91 panic("unreachable")
92}
93
94func p5() {
95 // Array to slice.
96 var p *[1 << 30]byte = nil
97 fb(p[0:]) // should crash
98}
99
100func p6() {
101 // Array to slice.
102 var p *[1 << 30]byte = nil
103 var _ []byte = p[10 : len(p)-10] // should crash
104}
105
106type T struct {
107 x [256 << 20]byte
108 i int
109}
110
111func f() *T {
112 return nil
113}
114
115var y *T
116var x = &y
117
118func p7() {
119 // Struct field access with large offset.
120 println(f().i) // should crash
121}
122
123func p8() {
124 // Struct field access with large offset.
125 println((*x).i) // should crash
126}
127
128func p9() {
129 // Struct field access with large offset.
130 var t *T
131 println(&t.i) // should crash
132}
133
134func p10() {
135 // Struct field access with large offset.
136 var t *T
137 println(t.i) // should crash
138}
Ian Lance Taylor578dc3a2013-04-24 08:13:01 -0700139
140type T1 struct {
141 T
142}
143
144type T2 struct {
145 *T1
146}
147
148func p11() {
149 t := &T2{}
150 p := &t.i
151 println(*p)
152}
153
154// ADDR(DOT(IND(p))) needs a check also
155func p12() {
156 var p *T = nil
157 println(*(&((*p).i)))
158}
Russ Cox1116f74e2013-09-05 23:06:34 -0400159
160// Tests suggested in golang.org/issue/6080.
161
162func p13() {
163 var x *[10]int
164 y := x[:]
165 _ = y
166}
167
168func p14() {
169 println((*[1]int)(nil)[:])
170}
171
172func p15() {
173 for i := range (*[1]int)(nil)[:] {
174 _ = i
175 }
176}
177
178func p16() {
179 for i, v := range (*[1]int)(nil)[:] {
180 _ = i + v
181 }
182}