1// errorcheck -0 -d=nil
2
3//go:build !wasm && !aix
4
5// Copyright 2013 The Go Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style
7// license that can be found in the LICENSE file.
8
9// Test that nil checks are removed.
10// Optimization is enabled.
11
12package p
13
14type Struct struct {
15	X int
16	Y float64
17}
18
19type BigStruct struct {
20	X int
21	Y float64
22	A [1 << 20]int
23	Z string
24}
25
26type Empty struct {
27}
28
29type Empty1 struct {
30	Empty
31}
32
33var (
34	intp       *int
35	arrayp     *[10]int
36	array0p    *[0]int
37	bigarrayp  *[1 << 26]int
38	structp    *Struct
39	bigstructp *BigStruct
40	emptyp     *Empty
41	empty1p    *Empty1
42)
43
44func f1() {
45	_ = *intp // ERROR "generated nil check"
46
47	// This one should be removed but the block copy needs
48	// to be turned into its own pseudo-op in order to see
49	// the indirect.
50	_ = *arrayp // ERROR "generated nil check"
51
52	// 0-byte indirect doesn't suffice.
53	// we don't registerize globals, so there are no removed.* nil checks.
54	_ = *array0p // ERROR "generated nil check"
55	_ = *array0p // ERROR "removed nil check"
56
57	_ = *intp    // ERROR "removed nil check"
58	_ = *arrayp  // ERROR "removed nil check"
59	_ = *structp // ERROR "generated nil check"
60	_ = *emptyp  // ERROR "generated nil check"
61	_ = *arrayp  // ERROR "removed nil check"
62}
63
64func f2() {
65	var (
66		intp       *int
67		arrayp     *[10]int
68		array0p    *[0]int
69		bigarrayp  *[1 << 20]int
70		structp    *Struct
71		bigstructp *BigStruct
72		emptyp     *Empty
73		empty1p    *Empty1
74	)
75
76	_ = *intp       // ERROR "generated nil check"
77	_ = *arrayp     // ERROR "generated nil check"
78	_ = *array0p    // ERROR "generated nil check"
79	_ = *array0p    // ERROR "removed.* nil check"
80	_ = *intp       // ERROR "removed.* nil check"
81	_ = *arrayp     // ERROR "removed.* nil check"
82	_ = *structp    // ERROR "generated nil check"
83	_ = *emptyp     // ERROR "generated nil check"
84	_ = *arrayp     // ERROR "removed.* nil check"
85	_ = *bigarrayp  // ERROR "generated nil check" ARM removed nil check before indirect!!
86	_ = *bigstructp // ERROR "generated nil check"
87	_ = *empty1p    // ERROR "generated nil check"
88}
89
90func fx10k() *[10000]int
91
92var b bool
93
94func f3(x *[10000]int) {
95	// Using a huge type and huge offsets so the compiler
96	// does not expect the memory hardware to fault.
97	_ = x[9999] // ERROR "generated nil check"
98
99	for {
100		if x[9999] != 0 { // ERROR "removed nil check"
101			break
102		}
103	}
104
105	x = fx10k()
106	_ = x[9999] // ERROR "generated nil check"
107	if b {
108		_ = x[9999] // ERROR "removed.* nil check"
109	} else {
110		_ = x[9999] // ERROR "removed.* nil check"
111	}
112	_ = x[9999] // ERROR "removed nil check"
113
114	x = fx10k()
115	if b {
116		_ = x[9999] // ERROR "generated nil check"
117	} else {
118		_ = x[9999] // ERROR "generated nil check"
119	}
120	_ = x[9999] // ERROR "generated nil check"
121
122	fx10k()
123	// This one is a bit redundant, if we figured out that
124	// x wasn't going to change across the function call.
125	// But it's a little complex to do and in practice doesn't
126	// matter enough.
127	_ = x[9999] // ERROR "removed nil check"
128}
129
130func f3a() {
131	x := fx10k()
132	y := fx10k()
133	z := fx10k()
134	_ = &x[9] // ERROR "generated nil check"
135	y = z
136	_ = &x[9] // ERROR "removed.* nil check"
137	x = y
138	_ = &x[9] // ERROR "generated nil check"
139}
140
141func f3b() {
142	x := fx10k()
143	y := fx10k()
144	_ = &x[9] // ERROR "generated nil check"
145	y = x
146	_ = &x[9] // ERROR "removed.* nil check"
147	x = y
148	_ = &x[9] // ERROR "removed.* nil check"
149}
150
151func fx10() *[10]int
152
153func f4(x *[10]int) {
154	// Most of these have no checks because a real memory reference follows,
155	// and the offset is small enough that if x is nil, the address will still be
156	// in the first unmapped page of memory.
157
158	_ = x[9] // ERROR "generated nil check" // bug: would like to remove this check (but nilcheck and load are in different blocks)
159
160	for {
161		if x[9] != 0 { // ERROR "removed nil check"
162			break
163		}
164	}
165
166	x = fx10()
167	_ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
168	if b {
169		_ = x[9] // ERROR "removed nil check"
170	} else {
171		_ = x[9] // ERROR "removed nil check"
172	}
173	_ = x[9] // ERROR "removed nil check"
174
175	x = fx10()
176	if b {
177		_ = x[9] // ERROR "generated nil check"  // bug would like to remove before indirect
178	} else {
179		_ = &x[9] // ERROR "generated nil check"
180	}
181	_ = x[9] // ERROR "generated nil check"  // bug would like to remove before indirect
182
183	fx10()
184	_ = x[9] // ERROR "removed nil check"
185
186	x = fx10()
187	y := fx10()
188	_ = &x[9] // ERROR "generated nil check"
189	y = x
190	_ = &x[9] // ERROR "removed[a-z ]* nil check"
191	x = y
192	_ = &x[9] // ERROR "removed[a-z ]* nil check"
193}
194
195func m1(m map[int][80]byte) byte {
196	v := m[3] // ERROR "removed nil check"
197	return v[5]
198}
199func m2(m map[int][800]byte) byte {
200	v := m[3] // ERROR "removed nil check"
201	return v[5]
202}
203func m3(m map[int][80]byte) (byte, bool) {
204	v, ok := m[3] // ERROR "removed nil check"
205	return v[5], ok
206}
207func m4(m map[int][800]byte) (byte, bool) {
208	v, ok := m[3] // ERROR "removed nil check"
209	return v[5], ok
210}
211func p1() byte {
212	p := new([100]byte)
213	return p[5] // ERROR "removed nil check"
214}
215
216type SS struct {
217	x byte
218}
219
220type TT struct {
221	SS
222}
223
224func f(t *TT) *byte {
225	// See issue 17242.
226	s := &t.SS  // ERROR "generated nil check"
227	return &s.x // ERROR "removed nil check"
228}
229
230// make sure not to do nil check for newobject
231func f7() (*Struct, float64) {
232	t := new(Struct)
233	p := &t.Y    // ERROR "removed nil check"
234	return t, *p // ERROR "removed nil check"
235}
236
237func f9() []int {
238	x := new([1]int)
239	x[0] = 1  // ERROR "removed nil check"
240	y := x[:] // ERROR "removed nil check"
241	return y
242}
243
244// See issue 42673.
245func f10(p **int) int {
246	return * // ERROR "removed nil check"
247	/* */
248	*p // ERROR "removed nil check"
249}
250
251func f11(x []byte) {
252	p := (*[0]byte)(x)
253	_ = *p // ERROR "generated nil check"
254	q := (*[4]byte)(x)
255	_ = *q // ERROR "removed nil check"
256}
257