1// run
2
3// 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
7// Test that the implementation catches nil ptr indirection
8// in a large address space.
9
10package 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.
19var dummy [256 << 20]byte // give us a big address space
20
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	shouldPanic(p11)
42	shouldPanic(p12)
43	shouldPanic(p13)
44	shouldPanic(p14)
45	shouldPanic(p15)
46	shouldPanic(p16)
47}
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}
139
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}
159
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}
183