1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8066103
  27  * @summary C2's range check smearing allows out of bound array accesses
  28  * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckSmearing
  29  *
  30  */
  31 
  32 public class TestRangeCheckSmearing {
  33 
  34     // first range check is i + max of all constants
  35     static int m1(int[] array, int i, boolean allaccesses) {
  36         int res = 0;
  37         res += array[i+9];
  38         if (allaccesses) {
  39             res += array[i+8];
  40             res += array[i+7];
  41             res += array[i+6];
  42             res += array[i+5];
  43             res += array[i+4];
  44             res += array[i+3];
  45             res += array[i+2];
  46             res += array[i+1];
  47         }
  48         return res;
  49     }
  50 
  51     // first range check is i + min of all constants
  52     static int m2(int[] array, int i, boolean allaccesses) {
  53         int res = 0;
  54         res += array[i+1];
  55         if (allaccesses) {
  56             res += array[i+2];
  57             res += array[i+3];
  58             res += array[i+4];
  59             res += array[i+5];
  60             res += array[i+6];
  61             res += array[i+7];
  62             res += array[i+8];
  63             res += array[i+9];
  64         }
  65         return res;
  66     }
  67 
  68     // first range check is not i + min/max of all constants
  69     static int m3(int[] array, int i, boolean allaccesses) {
  70         int res = 0;
  71         res += array[i+3];
  72         if (allaccesses) {
  73             res += array[i+2];
  74             res += array[i+1];
  75             res += array[i+4];
  76             res += array[i+5];
  77             res += array[i+6];
  78             res += array[i+7];
  79             res += array[i+8];
  80             res += array[i+9];
  81         }
  82         return res;
  83     }
  84 
  85     static int m4(int[] array, int i, boolean allaccesses) {
  86         int res = 0;
  87         res += array[i+3];
  88         if (allaccesses) {
  89             res += array[i+4];
  90             res += array[i+1];
  91             res += array[i+2];
  92             res += array[i+5];
  93             res += array[i+6];
  94             res += array[i+7];
  95             res += array[i+8];
  96             res += array[i+9];
  97         }
  98         return res;
  99     }
 100 
 101     static int m5(int[] array, int i, boolean allaccesses) {
 102         int res = 0;
 103         res += array[i+3];
 104         res += array[i+2];
 105         if (allaccesses) {
 106             res += array[i+1];
 107             res += array[i+4];
 108             res += array[i+5];
 109             res += array[i+6];
 110             res += array[i+7];
 111             res += array[i+8];
 112             res += array[i+9];
 113         }
 114         return res;
 115     }
 116 
 117     static int m6(int[] array, int i, boolean allaccesses) {
 118         int res = 0;
 119         res += array[i+3];
 120         res += array[i+4];
 121         if (allaccesses) {
 122             res += array[i+2];
 123             res += array[i+1];
 124             res += array[i+5];
 125             res += array[i+6];
 126             res += array[i+7];
 127             res += array[i+8];
 128             res += array[i+9];
 129         }
 130         return res;
 131     }
 132 
 133     static int m7(int[] array, int i, boolean allaccesses) {
 134         int res = 0;
 135         res += array[i+3];
 136         res += array[i+2];
 137         res += array[i+4];
 138         if (allaccesses) {
 139             res += array[i+1];
 140             res += array[i+5];
 141             res += array[i+6];
 142             res += array[i+7];
 143             res += array[i+8];
 144             res += array[i+9];
 145         }
 146         return res;
 147     }
 148 
 149     static int m8(int[] array, int i, boolean allaccesses) {
 150         int res = 0;
 151         res += array[i+3];
 152         res += array[i+4];
 153         res += array[i+2];
 154         if (allaccesses) {
 155             res += array[i+1];
 156             res += array[i+5];
 157             res += array[i+6];
 158             res += array[i+7];
 159             res += array[i+8];
 160             res += array[i+9];
 161         }
 162         return res;
 163     }
 164 
 165     static int m9(int[] array, int i) {
 166         int res = 0;
 167         res += array[i+3];
 168         res += array[i+3];
 169         return res;
 170     }
 171 
 172     static int m10(int[] array, int i, boolean allaccesses) {
 173         int res = 0;
 174         res += array[i+3];
 175         if (allaccesses) {
 176             res += array[i-2];
 177             res += array[i-1];
 178             res += array[i-4];
 179             res += array[i-5];
 180             res += array[i-6];
 181         }
 182         return res;
 183     }
 184 
 185     static int m11(int[] array, int i, boolean allaccesses) {
 186         int res = 0;
 187         res += array[i+3];
 188         if (allaccesses) {
 189             res += array[i-2];
 190             res += array[i-1];
 191             res += array[i-3];
 192             res += array[i+4];
 193             res += array[i+5];
 194             res += array[i+6];
 195         }
 196         return res;
 197     }
 198 
 199     static int m12(int[] array, int i, boolean allaccesses) {
 200         int res = 0;
 201         res += array[i+3];
 202         res += array[i-2];
 203         if (allaccesses) {
 204             res += array[i+5];
 205             res += array[i+6];
 206         }
 207         return res;
 208     }
 209 
 210     static int m13(int[] array, int i, boolean allaccesses) {
 211         int res = 0;
 212         res += array[i+3];
 213         res += array[i+6];
 214         if (allaccesses) {
 215             res += array[i-2];
 216             res += array[i-3];
 217         }
 218         return res;
 219     }
 220 
 221     static public void main(String[] args) {
 222         boolean success = true;
 223         boolean exception = false;
 224         int[] array = new int[10];
 225         
 226         for (int i = 0; i < 20000; i++) {
 227             m1(array, 0, (i % 2) == 0);
 228         }
 229 
 230         exception = false;
 231         try {
 232             m1(array, 8, false);
 233         } catch(ArrayIndexOutOfBoundsException aioob) {
 234             exception = true;
 235             System.out.println("ArrayIndexOutOfBoundsException thrown in m1");
 236         }
 237         if (!exception) {
 238             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m1");
 239             success = false;
 240         }
 241 
 242         for (int i = 0; i < 20000; i++) {
 243             m2(array, 0, (i % 2) == 0);
 244         }
 245 
 246         exception = false;
 247         try {
 248             m2(array, -9, false);
 249         } catch(ArrayIndexOutOfBoundsException aioob) {
 250             exception = true;
 251             System.out.println("ArrayIndexOutOfBoundsException thrown in m2");
 252         }
 253         if (!exception) {
 254             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m2");
 255             success = false;
 256         }
 257 
 258         for (int i = 0; i < 20000; i++) {
 259             m3(array, 0, (i % 2) == 0);
 260         }
 261 
 262         exception = false;
 263         try {
 264             m3(array, 8, false);
 265         } catch(ArrayIndexOutOfBoundsException aioob) {
 266             exception = true;
 267             System.out.println("ArrayIndexOutOfBoundsException thrown in m3");
 268         }
 269         if (!exception) {
 270             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m3");
 271             success = false;
 272         }
 273 
 274         for (int i = 0; i < 20000; i++) {
 275             m4(array, 0, (i % 2) == 0);
 276         }
 277 
 278         exception = false;
 279         try {
 280             m4(array, -9, false);
 281         } catch(ArrayIndexOutOfBoundsException aioob) {
 282             exception = true;
 283             System.out.println("ArrayIndexOutOfBoundsException thrown in m4");
 284         }
 285         if (!exception) {
 286             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m4");
 287             success = false;
 288         }
 289 
 290         for (int i = 0; i < 20000; i++) {
 291             m5(array, 0, (i % 2) == 0);
 292         }
 293 
 294         exception = false;
 295         try {
 296             m5(array, -3, false);
 297         } catch(ArrayIndexOutOfBoundsException aioob) {
 298             exception = true;
 299             System.out.println("ArrayIndexOutOfBoundsException thrown in m5");
 300         }
 301         if (!exception) {
 302             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m5");
 303             success = false;
 304         }
 305 
 306         for (int i = 0; i < 20000; i++) {
 307             m6(array, 0, (i % 2) == 0);
 308         }
 309 
 310         exception = false;
 311         try {
 312             m6(array, 6, false);
 313         } catch(ArrayIndexOutOfBoundsException aioob) {
 314             exception = true;
 315             System.out.println("ArrayIndexOutOfBoundsException thrown in m6");
 316         }
 317         if (!exception) {
 318             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m6");
 319             success = false;
 320         }
 321 
 322         for (int i = 0; i < 20000; i++) {
 323             m7(array, 0, (i % 2) == 0);
 324         }
 325 
 326         exception = false;
 327         try {
 328             m7(array, 6, false);
 329         } catch(ArrayIndexOutOfBoundsException aioob) {
 330             exception = true;
 331             System.out.println("ArrayIndexOutOfBoundsException thrown in m7");
 332         }
 333         if (!exception) {
 334             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m7");
 335             success = false;
 336         }
 337 
 338         for (int i = 0; i < 20000; i++) {
 339             m8(array, 0, (i % 2) == 0);
 340         }
 341 
 342         exception = false;
 343         try {
 344             m8(array, -3, false);
 345         } catch(ArrayIndexOutOfBoundsException aioob) {
 346             exception = true;
 347             System.out.println("ArrayIndexOutOfBoundsException thrown in m8");
 348         }
 349         if (!exception) {
 350             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m8");
 351             success = false;
 352         }
 353 
 354         for (int i = 0; i < 20000; i++) {
 355             m9(array, 0);
 356         }
 357 
 358 
 359         for (int i = 0; i < 20000; i++) {
 360             m10(array, 6, (i % 2) == 0);
 361         }
 362 
 363         exception = false;
 364         try {
 365             m10(array, 15, false);
 366         } catch(ArrayIndexOutOfBoundsException aioob) {
 367             exception = true;
 368             System.out.println("ArrayIndexOutOfBoundsException thrown in m10");
 369         }
 370         if (!exception) {
 371             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m10");
 372             success = false;
 373         }
 374 
 375         for (int i = 0; i < 20000; i++) {
 376             m11(array, 3, (i % 2) == 0);
 377         }
 378 
 379         exception = false;
 380         try {
 381             m11(array, 12, false);
 382         } catch(ArrayIndexOutOfBoundsException aioob) {
 383             exception = true;
 384             System.out.println("ArrayIndexOutOfBoundsException thrown in m11");
 385         }
 386         if (!exception) {
 387             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m11");
 388             success = false;
 389         }
 390 
 391         for (int i = 0; i < 20000; i++) {
 392             m12(array, 3, (i % 2) == 0);
 393         }
 394 
 395         exception = false;
 396         try {
 397             m12(array, -3, false);
 398         } catch(ArrayIndexOutOfBoundsException aioob) {
 399             exception = true;
 400             System.out.println("ArrayIndexOutOfBoundsException thrown in m12");
 401         }
 402         if (!exception) {
 403             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m12");
 404             success = false;
 405         }
 406 
 407         for (int i = 0; i < 20000; i++) {
 408             m13(array, 3, (i % 2) == 0);
 409         }
 410 
 411         exception = false;
 412         try {
 413             m13(array, 6, false);
 414         } catch(ArrayIndexOutOfBoundsException aioob) {
 415             exception = true;
 416             System.out.println("ArrayIndexOutOfBoundsException thrown in m13");
 417         }
 418         if (!exception) {
 419             System.out.println("ArrayIndexOutOfBoundsException was not thrown in m13");
 420             success = false;
 421         }
 422 
 423         if (!success) {
 424             throw new RuntimeException("Some tests failed");
 425         }
 426     }
 427 }