blob: 1c5b5d65b9c50a4ab81ad51385c1b3b67d37093b [file] [log] [blame]
Aart Bik22af3be2015-09-10 12:50:58 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Test on loop optimizations.
19//
20public class Main {
21
22 static int sResult;
23
24 //
25 // Various sequence variables where bound checks can be removed from loop.
26 //
27
28 /// CHECK-START: int Main.linear(int[]) BCE (before)
29 /// CHECK-DAG: BoundsCheck
30 /// CHECK-START: int Main.linear(int[]) BCE (after)
31 /// CHECK-NOT: BoundsCheck
32 private static int linear(int[] x) {
33 int result = 0;
34 for (int i = 0; i < x.length; i++) {
35 result += x[i];
36 }
37 return result;
38 }
39
40 /// CHECK-START: int Main.linearDown(int[]) BCE (before)
41 /// CHECK-DAG: BoundsCheck
42 /// CHECK-START: int Main.linearDown(int[]) BCE (after)
43 /// CHECK-NOT: BoundsCheck
44 private static int linearDown(int[] x) {
45 int result = 0;
46 for (int i = x.length - 1; i >= 0; i--) {
47 result += x[i];
48 }
49 return result;
50 }
51
52 /// CHECK-START: int Main.linearObscure(int[]) BCE (before)
53 /// CHECK-DAG: BoundsCheck
54 /// CHECK-START: int Main.linearObscure(int[]) BCE (after)
55 /// CHECK-NOT: BoundsCheck
56 private static int linearObscure(int[] x) {
57 int result = 0;
58 for (int i = x.length - 1; i >= 0; i--) {
59 int k = i + 5;
60 result += x[k - 5];
61 }
62 return result;
63 }
64
Aart Bikf475bee2015-09-16 12:50:25 -070065 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before)
66 /// CHECK-DAG: BoundsCheck
67 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after)
68 /// CHECK-NOT: BoundsCheck
69 private static int linearVeryObscure(int[] x) {
70 int result = 0;
71 for (int i = 0; i < x.length; i++) {
72 int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i;
73 result += x[k - 5];
74 }
75 return result;
76 }
77
Aart Bik22af3be2015-09-10 12:50:58 -070078 /// CHECK-START: int Main.linearWhile(int[]) BCE (before)
79 /// CHECK-DAG: BoundsCheck
80 /// CHECK-START: int Main.linearWhile(int[]) BCE (after)
81 /// CHECK-NOT: BoundsCheck
82 private static int linearWhile(int[] x) {
83 int i = 0;
84 int result = 0;
85 while (i < x.length) {
86 result += x[i++];
87 }
88 return result;
89 }
90
Aart Bikf475bee2015-09-16 12:50:25 -070091 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before)
92 /// CHECK-DAG: BoundsCheck
93 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after)
94 /// CHECK-NOT: BoundsCheck
95 private static int linearThreeWayPhi(int[] x) {
96 int result = 0;
97 for (int i = 0; i < x.length; ) {
98 if (x[i] == 5) {
99 i++;
100 continue;
101 }
102 result += x[i++];
103 }
104 return result;
105 }
106
107 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before)
108 /// CHECK-DAG: BoundsCheck
109 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after)
110 /// CHECK-NOT: BoundsCheck
111 private static int linearFourWayPhi(int[] x) {
112 int result = 0;
113 for (int i = 0; i < x.length; ) {
114 if (x[i] == 5) {
115 i++;
116 continue;
117 } else if (x[i] == 6) {
118 i++;
119 result += 7;
120 continue;
121 }
122 result += x[i++];
123 }
124 return result;
125 }
126
Aart Bik22af3be2015-09-10 12:50:58 -0700127 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before)
128 /// CHECK-DAG: BoundsCheck
129 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after)
130 /// CHECK-NOT: BoundsCheck
131 private static int wrapAroundThenLinear(int[] x) {
132 // Loop with wrap around (length - 1, 0, 1, 2, ..).
133 int w = x.length - 1;
134 int result = 0;
135 for (int i = 0; i < x.length; i++) {
136 result += x[w];
137 w = i;
138 }
139 return result;
140 }
141
Aart Bikf475bee2015-09-16 12:50:25 -0700142 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before)
143 /// CHECK-DAG: BoundsCheck
144 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after)
145 /// CHECK-NOT: BoundsCheck
146 private static int wrapAroundThenLinearThreeWayPhi(int[] x) {
147 // Loop with wrap around (length - 1, 0, 1, 2, ..).
148 int w = x.length - 1;
149 int result = 0;
150 for (int i = 0; i < x.length; ) {
151 if (x[w] == 1) {
152 w = i++;
153 continue;
154 }
155 result += x[w];
156 w = i++;
157 }
158 return result;
159 }
160
Aart Bik22af3be2015-09-10 12:50:58 -0700161 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before)
162 /// CHECK-DAG: BoundsCheck
163 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after)
164 /// CHECK-NOT: BoundsCheck
165 private static int[] linearWithParameter(int n) {
166 int[] x = new int[n];
167 for (int i = 0; i < n; i++) {
168 x[i] = i;
169 }
170 return x;
171 }
172
Aart Bikf475bee2015-09-16 12:50:25 -0700173 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before)
174 /// CHECK-DAG: BoundsCheck
175 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after)
176 /// CHECK-NOT: BoundsCheck
177 private static int[] linearCopy(int x[]) {
178 int n = x.length;
179 int y[] = new int[n];
180 for (int i = 0; i < n; i++) {
181 y[i] = x[i];
182 }
183 return y;
184 }
185
Aart Bik22af3be2015-09-10 12:50:58 -0700186 /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
187 /// CHECK-DAG: BoundsCheck
188 /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
189 /// CHECK-NOT: BoundsCheck
190 private static int linearWithCompoundStride() {
191 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
192 int result = 0;
193 for (int i = 0; i <= 12; ) {
194 i++;
195 result += x[i];
196 i++;
197 }
198 return result;
199 }
200
201 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
202 /// CHECK-DAG: BoundsCheck
203 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
204 /// CHECK-NOT: BoundsCheck
205 private static int linearWithLargePositiveStride() {
206 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
207 int result = 0;
208 int k = 0;
209 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700210 // reasonably large positive stride far away from upper bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700211 for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
212 result += x[k++];
213 }
214 return result;
215 }
216
217 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
218 /// CHECK-DAG: BoundsCheck
219 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
220 /// CHECK-DAG: BoundsCheck
221 private static int linearWithVeryLargePositiveStride() {
222 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
223 int result = 0;
224 int k = 0;
225 // Range analysis conservatively bails due to potential of wrap-around
226 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700227 for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700228 result += x[k++];
229 }
230 return result;
231 }
232
233 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
234 /// CHECK-DAG: BoundsCheck
235 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
236 /// CHECK-NOT: BoundsCheck
237 private static int linearWithLargeNegativeStride() {
238 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
239 int result = 0;
240 int k = 0;
241 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700242 // reasonably large negative stride far away from lower bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700243 for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
244 result += x[k++];
245 }
246 return result;
247 }
248
249 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
250 /// CHECK-DAG: BoundsCheck
251 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
252 /// CHECK-DAG: BoundsCheck
253 private static int linearWithVeryLargeNegativeStride() {
254 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
255 int result = 0;
256 int k = 0;
257 // Range analysis conservatively bails due to potential of wrap-around
258 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700259 for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700260 result += x[k++];
261 }
262 return result;
263 }
264
Aart Bikf475bee2015-09-16 12:50:25 -0700265 /// CHECK-START: int Main.linearForNE() BCE (before)
266 /// CHECK-DAG: BoundsCheck
267 /// CHECK-START: int Main.linearForNE() BCE (after)
268 /// CHECK-NOT: BoundsCheck
269 private static int linearForNE() {
270 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
271 int result = 0;
272 for (int i = 0; i != 10; i++) {
273 result += x[i];
274 }
275 return result;
276 }
277
278 /// CHECK-START: int Main.linearDoWhile() BCE (before)
279 /// CHECK-DAG: BoundsCheck
280 /// CHECK-START: int Main.linearDoWhile() BCE (after)
281 /// CHECK-DAG: BoundsCheck
282 private static int linearDoWhile() {
283 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
284 int result = 0;
285 int i = 0;
286 // TODO: make this work
287 do {
288 result += x[i++];
289 } while (i < 10);
290 return result;
291 }
292
293 /// CHECK-START: int Main.linearShort() BCE (before)
294 /// CHECK-DAG: BoundsCheck
295 /// CHECK-START: int Main.linearShort() BCE (after)
296 /// CHECK-DAG: BoundsCheck
297 private static int linearShort() {
298 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
299 int result = 0;
300 // TODO: make this work
301 for (short i = 0; i < 10; i++) {
302 result += x[i];
303 }
304 return result;
305 }
306
Aart Bik22af3be2015-09-10 12:50:58 -0700307 /// CHECK-START: int Main.periodicIdiom(int) BCE (before)
308 /// CHECK-DAG: BoundsCheck
309 /// CHECK-START: int Main.periodicIdiom(int) BCE (after)
310 /// CHECK-NOT: BoundsCheck
311 private static int periodicIdiom(int tc) {
312 int[] x = { 1, 3 };
313 // Loop with periodic sequence (0, 1).
314 int k = 0;
315 int result = 0;
316 for (int i = 0; i < tc; i++) {
317 result += x[k];
318 k = 1 - k;
319 }
320 return result;
321 }
322
323 /// CHECK-START: int Main.periodicSequence2(int) BCE (before)
324 /// CHECK-DAG: BoundsCheck
325 /// CHECK-START: int Main.periodicSequence2(int) BCE (after)
326 /// CHECK-NOT: BoundsCheck
327 private static int periodicSequence2(int tc) {
328 int[] x = { 1, 3 };
329 // Loop with periodic sequence (0, 1).
330 int k = 0;
331 int l = 1;
332 int result = 0;
333 for (int i = 0; i < tc; i++) {
334 result += x[k];
335 int t = l;
336 l = k;
337 k = t;
338 }
339 return result;
340 }
341
342 /// CHECK-START: int Main.periodicSequence4(int) BCE (before)
343 /// CHECK-DAG: BoundsCheck
344 /// CHECK-DAG: BoundsCheck
345 /// CHECK-DAG: BoundsCheck
346 /// CHECK-DAG: BoundsCheck
347 /// CHECK-START: int Main.periodicSequence4(int) BCE (after)
348 /// CHECK-NOT: BoundsCheck
349 private static int periodicSequence4(int tc) {
350 int[] x = { 1, 3, 5, 7 };
351 // Loop with periodic sequence (0, 1, 2, 3).
352 int k = 0;
353 int l = 1;
354 int m = 2;
355 int n = 3;
356 int result = 0;
357 for (int i = 0; i < tc; i++) {
358 result += x[k] + x[l] + x[m] + x[n]; // all used at once
359 int t = n;
360 n = k;
361 k = l;
362 l = m;
363 m = t;
364 }
365 return result;
366 }
367
Aart Bikf475bee2015-09-16 12:50:25 -0700368 /// CHECK-START: int Main.justRightUp1() BCE (before)
369 /// CHECK-DAG: BoundsCheck
370 /// CHECK-START: int Main.justRightUp1() BCE (after)
371 /// CHECK-NOT: BoundsCheck
372 private static int justRightUp1() {
373 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
374 int result = 0;
375 for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) {
376 result += x[k++];
377 }
378 return result;
379 }
380
381 /// CHECK-START: int Main.justRightUp2() BCE (before)
382 /// CHECK-DAG: BoundsCheck
383 /// CHECK-START: int Main.justRightUp2() BCE (after)
384 /// CHECK-NOT: BoundsCheck
385 private static int justRightUp2() {
386 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
387 int result = 0;
388 for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) {
389 result += x[i - Integer.MAX_VALUE + 10];
390 }
391 return result;
392 }
393
394 /// CHECK-START: int Main.justRightUp3() BCE (before)
395 /// CHECK-DAG: BoundsCheck
396 /// CHECK-START: int Main.justRightUp3() BCE (after)
397 /// CHECK-NOT: BoundsCheck
398 private static int justRightUp3() {
399 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
400 int result = 0;
401 for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) {
402 result += x[k++];
403 }
404 return result;
405 }
406
407 /// CHECK-START: int Main.justOOBUp() BCE (before)
408 /// CHECK-DAG: BoundsCheck
409 /// CHECK-START: int Main.justOOBUp() BCE (after)
410 /// CHECK-DAG: BoundsCheck
411 private static int justOOBUp() {
412 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
413 int result = 0;
414 // Infinite loop!
415 for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) {
416 result += x[k++];
417 }
418 return result;
419 }
420
421 /// CHECK-START: int Main.justRightDown1() BCE (before)
422 /// CHECK-DAG: BoundsCheck
423 /// CHECK-START: int Main.justRightDown1() BCE (after)
424 /// CHECK-NOT: BoundsCheck
425 private static int justRightDown1() {
426 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
427 int result = 0;
428 for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) {
429 result += x[k++];
430 }
431 return result;
432 }
433
434 /// CHECK-START: int Main.justRightDown2() BCE (before)
435 /// CHECK-DAG: BoundsCheck
436 /// CHECK-START: int Main.justRightDown2() BCE (after)
437 /// CHECK-NOT: BoundsCheck
438 private static int justRightDown2() {
439 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
440 int result = 0;
441 for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) {
442 result += x[Integer.MAX_VALUE + i];
443 }
444 return result;
445 }
446
447 /// CHECK-START: int Main.justRightDown3() BCE (before)
448 /// CHECK-DAG: BoundsCheck
449 /// CHECK-START: int Main.justRightDown3() BCE (after)
450 /// CHECK-NOT: BoundsCheck
451 private static int justRightDown3() {
452 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
453 int result = 0;
454 for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) {
455 result += x[k++];
456 }
457 return result;
458 }
459
460 /// CHECK-START: int Main.justOOBDown() BCE (before)
461 /// CHECK-DAG: BoundsCheck
462 /// CHECK-START: int Main.justOOBDown() BCE (after)
463 /// CHECK-DAG: BoundsCheck
464 private static int justOOBDown() {
465 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
466 int result = 0;
467 // Infinite loop!
468 for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) {
469 result += x[k++];
470 }
471 return result;
472 }
473
Aart Bik22af3be2015-09-10 12:50:58 -0700474 //
475 // Cases that actually go out of bounds. These test cases
476 // ensure the exceptions are thrown at the right places.
477 //
478
479 private static void lowerOOB(int[] x) {
480 for (int i = -1; i < x.length; i++) {
481 sResult += x[i];
482 }
483 }
484
485 private static void upperOOB(int[] x) {
486 for (int i = 0; i <= x.length; i++) {
487 sResult += x[i];
488 }
489 }
490
491 //
492 // Verifier.
493 //
494
495 public static void main(String[] args) {
496 int[] empty = { };
497 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
498
499 // Linear and wrap-around.
500 expectEquals(0, linear(empty));
501 expectEquals(55, linear(x));
502 expectEquals(0, linearDown(empty));
503 expectEquals(55, linearDown(x));
504 expectEquals(0, linearObscure(empty));
505 expectEquals(55, linearObscure(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700506 expectEquals(0, linearVeryObscure(empty));
507 expectEquals(55, linearVeryObscure(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700508 expectEquals(0, linearWhile(empty));
509 expectEquals(55, linearWhile(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700510 expectEquals(0, linearThreeWayPhi(empty));
511 expectEquals(50, linearThreeWayPhi(x));
512 expectEquals(0, linearFourWayPhi(empty));
513 expectEquals(51, linearFourWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700514 expectEquals(0, wrapAroundThenLinear(empty));
515 expectEquals(55, wrapAroundThenLinear(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700516 expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
517 expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700518
519 // Linear with parameter.
520 sResult = 0;
521 try {
522 linearWithParameter(-1);
523 } catch (NegativeArraySizeException e) {
524 sResult = 1;
525 }
526 expectEquals(1, sResult);
527 for (int n = 0; n < 32; n++) {
528 int[] r = linearWithParameter(n);
529 expectEquals(n, r.length);
530 for (int i = 0; i < n; i++) {
531 expectEquals(i, r[i]);
532 }
533 }
534
Aart Bikf475bee2015-09-16 12:50:25 -0700535 // Linear copy.
536 expectEquals(0, linearCopy(empty).length);
537 {
538 int[] r = linearCopy(x);
539 expectEquals(x.length, r.length);
540 for (int i = 0; i < x.length; i++) {
541 expectEquals(x[i], r[i]);
542 }
543 }
544
Aart Bik22af3be2015-09-10 12:50:58 -0700545 // Linear with non-unit strides.
546 expectEquals(56, linearWithCompoundStride());
547 expectEquals(66, linearWithLargePositiveStride());
548 expectEquals(66, linearWithVeryLargePositiveStride());
549 expectEquals(66, linearWithLargeNegativeStride());
550 expectEquals(66, linearWithVeryLargeNegativeStride());
551
Aart Bikf475bee2015-09-16 12:50:25 -0700552 // Special forms.
553 expectEquals(55, linearForNE());
554 expectEquals(55, linearDoWhile());
555 expectEquals(55, linearShort());
556
Aart Bik22af3be2015-09-10 12:50:58 -0700557 // Periodic adds (1, 3), one at the time.
558 expectEquals(0, periodicIdiom(-1));
559 for (int tc = 0; tc < 32; tc++) {
560 int expected = (tc >> 1) << 2;
561 if ((tc & 1) != 0)
562 expected += 1;
563 expectEquals(expected, periodicIdiom(tc));
564 }
565
566 // Periodic adds (1, 3), one at the time.
567 expectEquals(0, periodicSequence2(-1));
568 for (int tc = 0; tc < 32; tc++) {
569 int expected = (tc >> 1) << 2;
570 if ((tc & 1) != 0)
571 expected += 1;
572 expectEquals(expected, periodicSequence2(tc));
573 }
574
575 // Periodic adds (1, 3, 5, 7), all at once.
576 expectEquals(0, periodicSequence4(-1));
577 for (int tc = 0; tc < 32; tc++) {
578 expectEquals(tc * 16, periodicSequence4(tc));
579 }
580
Aart Bikf475bee2015-09-16 12:50:25 -0700581 // Large bounds.
582 expectEquals(55, justRightUp1());
583 expectEquals(55, justRightUp2());
584 expectEquals(55, justRightUp3());
585 expectEquals(55, justRightDown1());
586 expectEquals(55, justRightDown2());
587 expectEquals(55, justRightDown3());
588 sResult = 0;
589 try {
590 justOOBUp();
591 } catch (ArrayIndexOutOfBoundsException e) {
592 sResult = 1;
593 }
594 expectEquals(1, sResult);
595 sResult = 0;
596 try {
597 justOOBDown();
598 } catch (ArrayIndexOutOfBoundsException e) {
599 sResult = 1;
600 }
601 expectEquals(1, sResult);
602
Aart Bik22af3be2015-09-10 12:50:58 -0700603 // Lower bound goes OOB.
604 sResult = 0;
605 try {
606 lowerOOB(x);
607 } catch (ArrayIndexOutOfBoundsException e) {
608 sResult += 1000;
609 }
610 expectEquals(1000, sResult);
611
612 // Upper bound goes OOB.
613 sResult = 0;
614 try {
615 upperOOB(x);
616 } catch (ArrayIndexOutOfBoundsException e) {
617 sResult += 1000;
618 }
619 expectEquals(1055, sResult);
620
621 }
622
623 private static void expectEquals(int expected, int result) {
624 if (expected != result) {
625 throw new Error("Expected: " + expected + ", found: " + result);
626 }
627 }
628}