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