1// errorcheck -0 -m -l
2
3// Copyright 2012 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, using compiler diagnostic flags, that bounds check elimination
8// is eliminating the correct checks.
9
10package foo
11
12var (
13	s []int
14
15	a1 [1]int
16	a1k [1000]int
17	a100k [100000]int
18
19	p1 *[1]int
20	p1k *[1000]int
21	p100k *[100000]int
22
23	i int
24	ui uint
25	i8 int8
26	ui8 uint8
27	i16 int16
28	ui16 uint16
29	i32 int32
30	ui32 uint32
31	i64 int64
32	ui64 uint64
33)
34
35func main() {
36	// Most things need checks.
37	use(s[i])
38	use(a1[i])
39	use(a1k[i])
40	use(a100k[i])
41	use(p1[i])
42	use(p1k[i])
43	use(p100k[i])
44
45	use(s[ui])
46	use(a1[ui])
47	use(a1k[ui])
48	use(a100k[ui])
49	use(p1[ui])
50	use(p1k[ui])
51	use(p100k[ui])
52
53	use(s[i8])
54	use(a1[i8])
55	use(a1k[i8])
56	use(a100k[i8])
57	use(p1[i8])
58	use(p1k[i8])
59	use(p100k[i8])
60
61	// Unsigned 8-bit numbers don't need checks for len >= 2⁸.
62	use(s[ui8])
63	use(a1[ui8])
64	use(a1k[ui8])  // ERROR "index bounds check elided"
65	use(a100k[ui8])  // ERROR "index bounds check elided"
66	use(p1[ui8])
67	use(p1k[ui8])  // ERROR "index bounds check elided"
68	use(p100k[ui8])  // ERROR "index bounds check elided"
69
70	use(s[i16])
71	use(a1[i16])
72	use(a1k[i16])
73	use(a100k[i16])
74	use(p1[i16])
75	use(p1k[i16])
76	use(p100k[i16])
77
78	// Unsigned 16-bit numbers don't need checks for len >= 2¹⁶.
79	use(s[ui16])
80	use(a1[ui16])
81	use(a1k[ui16])
82	use(a100k[ui16])  // ERROR "index bounds check elided"
83	use(p1[ui16])
84	use(p1k[ui16])
85	use(p100k[ui16])  // ERROR "index bounds check elided"
86
87	use(s[i32])
88	use(a1[i32])
89	use(a1k[i32])
90	use(a100k[i32])
91	use(p1[i32])
92	use(p1k[i32])
93	use(p100k[i32])
94
95	use(s[ui32])
96	use(a1[ui32])
97	use(a1k[ui32])
98	use(a100k[ui32])
99	use(p1[ui32])
100	use(p1k[ui32])
101	use(p100k[ui32])
102
103	use(s[i64])
104	use(a1[i64])
105	use(a1k[i64])
106	use(a100k[i64])
107	use(p1[i64])
108	use(p1k[i64])
109	use(p100k[i64])
110
111	use(s[ui64])
112	use(a1[ui64])
113	use(a1k[ui64])
114	use(a100k[ui64])
115	use(p1[ui64])
116	use(p1k[ui64])
117	use(p100k[ui64])
118
119	// Mod truncates the maximum value to one less than the argument,
120	// but signed mod can be negative, so only unsigned mod counts.
121	use(s[i%999])
122	use(a1[i%999])
123	use(a1k[i%999])
124	use(a100k[i%999])
125	use(p1[i%999])
126	use(p1k[i%999])
127	use(p100k[i%999])
128
129	use(s[ui%999])
130	use(a1[ui%999])
131	use(a1k[ui%999])  // ERROR "index bounds check elided"
132	use(a100k[ui%999])  // ERROR "index bounds check elided"
133	use(p1[ui%999])
134	use(p1k[ui%999])  // ERROR "index bounds check elided"
135	use(p100k[ui%999])  // ERROR "index bounds check elided"
136
137	use(s[i%1000])
138	use(a1[i%1000])
139	use(a1k[i%1000])
140	use(a100k[i%1000])
141	use(p1[i%1000])
142	use(p1k[i%1000])
143	use(p100k[i%1000])
144
145	use(s[ui%1000])
146	use(a1[ui%1000])
147	use(a1k[ui%1000])  // ERROR "index bounds check elided"
148	use(a100k[ui%1000])  // ERROR "index bounds check elided"
149	use(p1[ui%1000])
150	use(p1k[ui%1000])  // ERROR "index bounds check elided"
151	use(p100k[ui%1000])  // ERROR "index bounds check elided"
152
153	use(s[i%1001])
154	use(a1[i%1001])
155	use(a1k[i%1001])
156	use(a100k[i%1001])
157	use(p1[i%1001])
158	use(p1k[i%1001])
159	use(p100k[i%1001])
160
161	use(s[ui%1001])
162	use(a1[ui%1001])
163	use(a1k[ui%1001])
164	use(a100k[ui%1001])  // ERROR "index bounds check elided"
165	use(p1[ui%1001])
166	use(p1k[ui%1001])
167	use(p100k[ui%1001])  // ERROR "index bounds check elided"
168
169	// Bitwise and truncates the maximum value to the mask value.
170	// The result (for a positive mask) cannot be negative, so elision
171	// applies to both signed and unsigned indexes.
172	use(s[i&999])
173	use(a1[i&999])
174	use(a1k[i&999])  // ERROR "index bounds check elided"
175	use(a100k[i&999])  // ERROR "index bounds check elided"
176	use(p1[i&999])
177	use(p1k[i&999])  // ERROR "index bounds check elided"
178	use(p100k[i&999])  // ERROR "index bounds check elided"
179
180	use(s[ui&999])
181	use(a1[ui&999])
182	use(a1k[ui&999])  // ERROR "index bounds check elided"
183	use(a100k[ui&999])  // ERROR "index bounds check elided"
184	use(p1[ui&999])
185	use(p1k[ui&999])  // ERROR "index bounds check elided"
186	use(p100k[ui&999])  // ERROR "index bounds check elided"
187
188	use(s[i&1000])
189	use(a1[i&1000])
190	use(a1k[i&1000])
191	use(a100k[i&1000])  // ERROR "index bounds check elided"
192	use(p1[i&1000])
193	use(p1k[i&1000])
194	use(p100k[i&1000])  // ERROR "index bounds check elided"
195
196	use(s[ui&1000])
197	use(a1[ui&1000])
198	use(a1k[ui&1000])
199	use(a100k[ui&1000])  // ERROR "index bounds check elided"
200	use(p1[ui&1000])
201	use(p1k[ui&1000])
202	use(p100k[ui&1000])  // ERROR "index bounds check elided"
203
204	// Right shift cuts the effective number of bits in the index,
205	// but only for unsigned (signed stays negative).
206	use(s[i32>>22])
207	use(a1[i32>>22])
208	use(a1k[i32>>22])
209	use(a100k[i32>>22])
210	use(p1[i32>>22])
211	use(p1k[i32>>22])
212	use(p100k[i32>>22])
213
214	use(s[ui32>>22])
215	use(a1[ui32>>22])
216	use(a1k[ui32>>22])
217	use(a100k[ui32>>22])  // ERROR "index bounds check elided"
218	use(p1[ui32>>22])
219	use(p1k[ui32>>22])
220	use(p100k[ui32>>22])  // ERROR "index bounds check elided"
221
222	use(s[i32>>23])
223	use(a1[i32>>23])
224	use(a1k[i32>>23])
225	use(a100k[i32>>23])
226	use(p1[i32>>23])
227	use(p1k[i32>>23])
228	use(p100k[i32>>23])
229
230	use(s[ui32>>23])
231	use(a1[ui32>>23])
232	use(a1k[ui32>>23])  // ERROR "index bounds check elided"
233	use(a100k[ui32>>23])  // ERROR "index bounds check elided"
234	use(p1[ui32>>23])
235	use(p1k[ui32>>23])  // ERROR "index bounds check elided"
236	use(p100k[ui32>>23])  // ERROR "index bounds check elided"
237
238	// Division cuts the range like right shift does.
239	use(s[i/1e6])
240	use(a1[i/1e6])
241	use(a1k[i/1e6])
242	use(a100k[i/1e6])
243	use(p1[i/1e6])
244	use(p1k[i/1e6])
245	use(p100k[i/1e6])
246
247	use(s[ui/1e6])
248	use(a1[ui/1e6])
249	use(a1k[ui/1e6])
250	use(p1[ui/1e6])
251	use(p1k[ui/1e6])
252
253	use(s[i/1e7])
254	use(a1[i/1e7])
255	use(a1k[i/1e7])
256	use(a100k[i/1e7])
257	use(p1[i/1e7])
258	use(p1k[i/1e7])
259	use(p100k[i/1e7])
260
261	use(s[ui/1e7])
262	use(a1[ui/1e7])
263	use(p1[ui/1e7])
264}
265
266var sum int
267
268func use(x int) {
269	sum += x
270}
271