blob: 9a96bb53867341fb248a73c8b37e267d1fbc1e23 [file] [log] [blame]
David Chase729abfa2015-10-26 17:34:06 -04001// errorcheck -0 -d=nil
David Chase729abfa2015-10-26 17:34:06 -04002
Emmanuel Odeke53fd5222016-04-10 14:32:26 -07003// Copyright 2013 The Go Authors. All rights reserved.
David Chase729abfa2015-10-26 17:34:06 -04004// 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 nil checks are removed.
8// Optimization is enabled.
9
10package p
11
12type Struct struct {
13 X int
14 Y float64
15}
16
17type BigStruct struct {
18 X int
19 Y float64
20 A [1 << 20]int
21 Z string
22}
23
24type Empty struct {
25}
26
27type Empty1 struct {
28 Empty
29}
30
31var (
32 intp *int
33 arrayp *[10]int
34 array0p *[0]int
35 bigarrayp *[1 << 26]int
36 structp *Struct
37 bigstructp *BigStruct
38 emptyp *Empty
39 empty1p *Empty1
40)
41
42func f1() {
Cherry Zhang98061fa2017-01-20 10:38:05 -050043 _ = *intp // ERROR "generated nil check"
David Chase729abfa2015-10-26 17:34:06 -040044
45 // This one should be removed but the block copy needs
46 // to be turned into its own pseudo-op in order to see
47 // the indirect.
Cherry Zhang98061fa2017-01-20 10:38:05 -050048 _ = *arrayp // ERROR "generated nil check"
David Chase729abfa2015-10-26 17:34:06 -040049
50 // 0-byte indirect doesn't suffice.
51 // we don't registerize globals, so there are no removed.* nil checks.
Keith Randall256a6052017-01-20 09:54:10 -080052 _ = *array0p // ERROR "generated nil check"
Cherry Zhang98061fa2017-01-20 10:38:05 -050053 _ = *array0p // ERROR "removed nil check"
David Chase729abfa2015-10-26 17:34:06 -040054
Cherry Zhang98061fa2017-01-20 10:38:05 -050055 _ = *intp // ERROR "removed nil check"
David Chase729abfa2015-10-26 17:34:06 -040056 _ = *arrayp // ERROR "removed nil check"
57 _ = *structp // ERROR "generated nil check"
58 _ = *emptyp // ERROR "generated nil check"
Cherry Zhang98061fa2017-01-20 10:38:05 -050059 _ = *arrayp // ERROR "removed nil check"
David Chase729abfa2015-10-26 17:34:06 -040060}
61
62func f2() {
63 var (
64 intp *int
65 arrayp *[10]int
66 array0p *[0]int
67 bigarrayp *[1 << 20]int
68 structp *Struct
69 bigstructp *BigStruct
70 emptyp *Empty
71 empty1p *Empty1
72 )
73
Keith Randall256a6052017-01-20 09:54:10 -080074 _ = *intp // ERROR "generated nil check"
Cherry Zhang98061fa2017-01-20 10:38:05 -050075 _ = *arrayp // ERROR "generated nil check"
76 _ = *array0p // ERROR "generated nil check"
77 _ = *array0p // ERROR "removed.* nil check"
78 _ = *intp // ERROR "removed.* nil check"
Keith Randall256a6052017-01-20 09:54:10 -080079 _ = *arrayp // ERROR "removed.* nil check"
David Chase729abfa2015-10-26 17:34:06 -040080 _ = *structp // ERROR "generated nil check"
81 _ = *emptyp // ERROR "generated nil check"
Cherry Zhang98061fa2017-01-20 10:38:05 -050082 _ = *arrayp // ERROR "removed.* nil check"
David Chase729abfa2015-10-26 17:34:06 -040083 _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
84 _ = *bigstructp // ERROR "generated nil check"
85 _ = *empty1p // ERROR "generated nil check"
86}
87
88func fx10k() *[10000]int
89
90var b bool
91
92func f3(x *[10000]int) {
93 // Using a huge type and huge offsets so the compiler
94 // does not expect the memory hardware to fault.
95 _ = x[9999] // ERROR "generated nil check"
96
97 for {
98 if x[9999] != 0 { // ERROR "removed nil check"
99 break
100 }
101 }
102
103 x = fx10k()
104 _ = x[9999] // ERROR "generated nil check"
105 if b {
106 _ = x[9999] // ERROR "removed.* nil check"
107 } else {
108 _ = x[9999] // ERROR "removed.* nil check"
109 }
110 _ = x[9999] // ERROR "removed nil check"
111
112 x = fx10k()
113 if b {
114 _ = x[9999] // ERROR "generated nil check"
115 } else {
116 _ = x[9999] // ERROR "generated nil check"
117 }
118 _ = x[9999] // ERROR "generated nil check"
119
120 fx10k()
121 // This one is a bit redundant, if we figured out that
122 // x wasn't going to change across the function call.
123 // But it's a little complex to do and in practice doesn't
124 // matter enough.
Cherry Zhang98061fa2017-01-20 10:38:05 -0500125 _ = x[9999] // ERROR "removed nil check"
David Chase729abfa2015-10-26 17:34:06 -0400126}
127
128func f3a() {
129 x := fx10k()
130 y := fx10k()
131 z := fx10k()
Keith Randall256a6052017-01-20 09:54:10 -0800132 _ = &x[9] // ERROR "generated nil check"
Cherry Zhang98061fa2017-01-20 10:38:05 -0500133 y = z
134 _ = &x[9] // ERROR "removed.* nil check"
David Chase729abfa2015-10-26 17:34:06 -0400135 x = y
136 _ = &x[9] // ERROR "generated nil check"
137}
138
139func f3b() {
140 x := fx10k()
141 y := fx10k()
Cherry Zhang98061fa2017-01-20 10:38:05 -0500142 _ = &x[9] // ERROR "generated nil check"
David Chase729abfa2015-10-26 17:34:06 -0400143 y = x
144 _ = &x[9] // ERROR "removed.* nil check"
145 x = y
Cherry Zhang98061fa2017-01-20 10:38:05 -0500146 _ = &x[9] // ERROR "removed.* nil check"
David Chase729abfa2015-10-26 17:34:06 -0400147}
148
149func fx10() *[10]int
150
151func f4(x *[10]int) {
152 // Most of these have no checks because a real memory reference follows,
153 // and the offset is small enough that if x is nil, the address will still be
154 // in the first unmapped page of memory.
155
Keith Randall3134ab32016-09-13 17:01:01 -0700156 _ = x[9] // ERROR "generated nil check" // bug: would like to remove this check (but nilcheck and load are in different blocks)
David Chase729abfa2015-10-26 17:34:06 -0400157
158 for {
159 if x[9] != 0 { // ERROR "removed nil check"
160 break
161 }
162 }
163
164 x = fx10()
165 _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
166 if b {
167 _ = x[9] // ERROR "removed nil check"
168 } else {
169 _ = x[9] // ERROR "removed nil check"
170 }
171 _ = x[9] // ERROR "removed nil check"
172
173 x = fx10()
174 if b {
175 _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
176 } else {
177 _ = &x[9] // ERROR "generated nil check"
178 }
179 _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
180
181 fx10()
Cherry Zhang98061fa2017-01-20 10:38:05 -0500182 _ = x[9] // ERROR "removed nil check"
David Chase729abfa2015-10-26 17:34:06 -0400183
184 x = fx10()
185 y := fx10()
Cherry Zhang98061fa2017-01-20 10:38:05 -0500186 _ = &x[9] // ERROR "generated nil check"
David Chase729abfa2015-10-26 17:34:06 -0400187 y = x
188 _ = &x[9] // ERROR "removed[a-z ]* nil check"
189 x = y
Cherry Zhang98061fa2017-01-20 10:38:05 -0500190 _ = &x[9] // ERROR "removed[a-z ]* nil check"
David Chase729abfa2015-10-26 17:34:06 -0400191}
Keith Randall4a346e72016-02-25 13:45:22 -0800192
193func f5(p *float32, q *float64, r *float32, s *float64) float64 {
194 x := float64(*p) // ERROR "removed nil check"
195 y := *q // ERROR "removed nil check"
196 *r = 7 // ERROR "removed nil check"
197 *s = 9 // ERROR "removed nil check"
198 return x + y
199}
200
201type T [29]byte
202
203func f6(p, q *T) {
204 x := *p // ERROR "removed nil check"
205 *q = x // ERROR "removed nil check"
206}
Keith Randall3c1a4c12016-04-19 21:06:53 -0700207
208func m1(m map[int][80]byte) byte {
209 v := m[3] // ERROR "removed nil check"
210 return v[5]
211}
212func m2(m map[int][800]byte) byte {
213 v := m[3] // ERROR "removed nil check"
214 return v[5]
215}
216func m3(m map[int][80]byte) (byte, bool) {
217 v, ok := m[3] // ERROR "removed nil check"
218 return v[5], ok
219}
220func m4(m map[int][800]byte) (byte, bool) {
221 v, ok := m[3] // ERROR "removed nil check"
222 return v[5], ok
223}
224func p1() byte {
225 p := new([100]byte)
226 return p[5] // ERROR "removed nil check"
227}
Cherry Zhang04e76f22016-08-17 10:32:39 -0400228
229// make sure not to do nil check for access of PAUTOHEAP
230//go:noinline
231func (p *Struct) m() {}
232func c1() {
233 var x Struct
234 func() { x.m() }() // ERROR "removed nil check"
235}
Keith Randall98938182016-09-27 14:39:27 -0700236
237type SS struct {
238 x byte
239}
240
241type TT struct {
242 SS
243}
244
245func f(t *TT) *byte {
246 // See issue 17242.
247 s := &t.SS // ERROR "removed nil check"
248 return &s.x // ERROR "generated nil check"
249}
Cherry Zhang4d07d3e2016-09-28 10:20:24 -0400250
251// make sure not to do nil check for newobject
252func f7() (*Struct, float64) {
253 t := new(Struct)
254 p := &t.Y // ERROR "removed nil check"
255 return t, *p // ERROR "removed nil check"
256}
Cherry Zhangfddc0042016-11-21 11:31:39 -0500257
258// make sure to remove nil check for memory move (issue #18003)
259func f8(t *[8]int) [8]int {
260 return *t // ERROR "removed nil check"
261}
Keith Randallf1517ec2017-08-24 15:23:27 -0700262
263func f9() []int {
264 x := new([1]int)
265 x[0] = 1 // ERROR "removed nil check"
266 y := x[:] // ERROR "removed nil check"
267 return y
268}