]> Cypherpunks.ru repositories - gostls13.git/blob - test/nilptr.go
test/[n-r]*.go: add documentation
[gostls13.git] / test / nilptr.go
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
10 package main
11
12 import "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.
19 var dummy [256 << 20]byte // give us a big address space
20
21 func 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
43 func shouldPanic(f func()) {
44         defer func() {
45                 if recover() == nil {
46                         panic("memory reference did not panic")
47                 }
48         }()
49         f()
50 }
51
52 func 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
58 var xb byte
59
60 func 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
68 func p3() {
69         // Array to slice.
70         var p *[1 << 30]byte = nil
71         var x []byte = p[0:] // should panic
72         _ = x
73 }
74
75 var q *[1 << 30]byte
76
77 func 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
84 func fb([]byte) {
85         panic("unreachable")
86 }
87
88 func p5() {
89         // Array to slice.
90         var p *[1 << 30]byte = nil
91         fb(p[0:]) // should crash
92 }
93
94 func p6() {
95         // Array to slice.
96         var p *[1 << 30]byte = nil
97         var _ []byte = p[10 : len(p)-10] // should crash
98 }
99
100 type T struct {
101         x [256 << 20]byte
102         i int
103 }
104
105 func f() *T {
106         return nil
107 }
108
109 var y *T
110 var x = &y
111
112 func p7() {
113         // Struct field access with large offset.
114         println(f().i) // should crash
115 }
116
117 func p8() {
118         // Struct field access with large offset.
119         println((*x).i) // should crash
120 }
121
122 func p9() {
123         // Struct field access with large offset.
124         var t *T
125         println(&t.i) // should crash
126 }
127
128 func p10() {
129         // Struct field access with large offset.
130         var t *T
131         println(t.i) // should crash
132 }