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}
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}
133