1 /*
  2  * Copyright (c) 2021, 2024, 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 8260034 8260225 8260283 8261037 8261874 8262128 8262831 8306986
 27  * @summary A selection of generated tests that triggered bugs not covered by other tests.
 28  * @enablePreview
 29  * @modules java.base/jdk.internal.value
 30  *          java.base/jdk.internal.vm.annotation
 31  * @run main/othervm -Xbatch
 32  *                   compiler.valhalla.inlinetypes.TestGenerated
 33  * @run main/othervm -Xbatch -XX:FlatArrayElementMaxSize=0
 34  *                   compiler.valhalla.inlinetypes.TestGenerated
 35  */
 36 
 37 package compiler.valhalla.inlinetypes;
 38 
 39 import jdk.internal.value.ValueClass;
 40 import jdk.internal.vm.annotation.ImplicitlyConstructible;
 41 import jdk.internal.vm.annotation.LooselyConsistentValue;
 42 import jdk.internal.vm.annotation.NullRestricted;
 43 
 44 @ImplicitlyConstructible
 45 @LooselyConsistentValue
 46 value class EmptyPrimitive {
 47 
 48 }
 49 
 50 value class EmptyValue {
 51 
 52 }
 53 
 54 @ImplicitlyConstructible
 55 @LooselyConsistentValue
 56 value class MyValue1 {
 57     int x = 42;
 58     int[] array = new int[1];
 59 }
 60 
 61 @ImplicitlyConstructible
 62 @LooselyConsistentValue
 63 value class MyValue2 {
 64     int[] a = new int[1];
 65     int[] b = new int[6];
 66     int[] c = new int[5];
 67 }
 68 
 69 @ImplicitlyConstructible
 70 @LooselyConsistentValue
 71 value class MyValue3 {
 72     int[] intArray = new int[1];
 73     float[] floatArray = new float[1];
 74 }
 75 
 76 @ImplicitlyConstructible
 77 @LooselyConsistentValue
 78 value class MyValue4 {
 79     short b = 2;
 80     int c = 8;
 81 }
 82 
 83 class MyValue4Wrapper {
 84     public MyValue4 val;
 85 
 86     public MyValue4Wrapper(MyValue4 val) {
 87         this.val = val;
 88     }
 89 }
 90 
 91 @ImplicitlyConstructible
 92 @LooselyConsistentValue
 93 value class MyValue5 {
 94     int b = 2;
 95 }
 96 
 97 value class MyValue6 {
 98     int x = 42;
 99 }
100 
101 public class TestGenerated {
102     @NullRestricted
103     EmptyPrimitive f1 = new EmptyPrimitive();
104     @NullRestricted
105     EmptyPrimitive f2 = new EmptyPrimitive();
106 
107     void test1(EmptyPrimitive[] array) {
108         for (int i = 0; i < 10; ++i) {
109             f1 = array[0];
110             f2 = array[0];
111         }
112     }
113 
114     MyValue1 test2(MyValue1[] array) {
115         MyValue1 res = new MyValue1();
116         for (int i = 0; i < array.length; ++i) {
117             res = array[i];
118         }
119         for (int i = 0; i < 1000; ++i) {
120 
121         }
122         return res;
123     }
124 
125     void test3(MyValue1[] array) {
126         for (int i = 0; i < array.length; ++i) {
127             array[i] = new MyValue1();
128         }
129         for (int i = 0; i < 1000; ++i) {
130 
131         }
132     }
133 
134     void test4(MyValue1[] array) {
135         array[0].array[0] = 0;
136     }
137 
138     int test5(MyValue1[] array) {
139         return array[0].array[0];
140     }
141 
142     long f3;
143     @NullRestricted
144     MyValue1 f4 = new MyValue1();
145 
146     void test6() {
147         f3 = 123L;
148         int res = f4.x;
149         if (res != 42) {
150             throw new RuntimeException("test6 failed");
151         }
152     }
153 
154     @NullRestricted
155     MyValue2 f5;
156 
157     void test7(boolean b) {
158         MyValue2[] array1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 6);
159         array1[0] = new MyValue2();
160         array1[1] = new MyValue2();
161         array1[2] = new MyValue2();
162         array1[3] = new MyValue2();
163         array1[4] = new MyValue2();
164         array1[5] = new MyValue2();
165 
166         MyValue2 h = new MyValue2();
167         MyValue2 n = new MyValue2();
168         int[] array2 = new int[1];
169 
170         for (int i = 0; i < 10; ++i) {
171           for (int j = 0; j < 10; ++j) {
172             array1[0] = array1[0];
173             if (i == 1) {
174               h = h;
175               array2[0] *= 42;
176             }
177           }
178         }
179         if (b) {
180           f5 = n;
181         }
182     }
183 
184     boolean test8(MyValue1[] array) {
185         return array[0].array == array[0].array;
186     }
187 
188     void test9(boolean b) {
189         MyValue1[] array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
190         if (b) {
191             for (int i = 0; i < 10; ++i) {
192                 if (array != array) {
193                     array = null;
194                 }
195             }
196         }
197     }
198 
199     int[] f6 = new int[1];
200 
201     void test10(MyValue3[] array) {
202         float[] floatArray = array[0].floatArray;
203         if (f6 == f6) {
204             f6 = array[0].intArray;
205         }
206     }
207 
208     void test11(MyValue3[] array) {
209         float[] floatArray = array[0].floatArray;
210         if (array[0].intArray[0] != 42) {
211             throw new RuntimeException("test11 failed");
212         }
213     }
214 
215     MyValue4[] d = (MyValue4[])ValueClass.newNullRestrictedArray(MyValue4.class, 1);
216     @NullRestricted
217     MyValue4 e;
218     byte f;
219 
220     byte test12() {
221         MyValue4 i = new MyValue4();
222         for (int j = 0; j < 6; ++j) {
223             MyValue4[] k = (MyValue4[])ValueClass.newNullRestrictedArray(MyValue4.class, 0);
224             if (i.b < 101) {
225                 i = e;
226             }
227             for (int l = 0; l < 9; ++l) {
228                 MyValue4 m = new MyValue4();
229                 i = m;
230             }
231         }
232         if (d[0].c > 1) {
233             for (int n = 0; n < 7; ++n) {
234             }
235         }
236         return f;
237     }
238 
239     int test13_iField;
240     @NullRestricted
241     MyValue5 test13_c;
242     @NullRestricted
243     MyValue5 test13_t;
244 
245     void test13(MyValue5[] array) {
246         for (int i = 0; i < 10; ++i) {
247             for (int j = 0; j < 10; ++j) {
248                 test13_iField = 6;
249             }
250             for (int j = 0; j < 2; ++j) {
251                 test13_iField += array[0].b;
252             }
253             MyValue5[] array2 = (MyValue5[])ValueClass.newNullRestrictedArray(MyValue5.class, 1);
254             test13_c = array[0];
255             array2[0] = test13_t;
256         }
257     }
258 
259     void test14(boolean b, MyValue4 val) {
260         for (int i = 0; i < 10; ++i) {
261             if (b) {
262                 val = new MyValue4();
263             }
264             MyValue4[] array = (MyValue4[])ValueClass.newNullRestrictedArray(MyValue4.class, 1);
265             array[0] = val;
266 
267             for (int j = 0; j < 5; ++j) {
268                 for (int k = 0; k < 5; ++k) {
269                 }
270             }
271         }
272     }
273 
274     void test15() {
275         MyValue4 val = new MyValue4();
276         for (int i = 0; i < 10; ++i) {
277             for (int j = 0; j < 10; ++j) {
278                 MyValue4[] array = (MyValue4[])ValueClass.newNullRestrictedArray(MyValue4.class, 1);
279                 for (int k = 0; k < 10; ++k) {
280                     array[0] = val;
281                     val = array[0];
282                 }
283             }
284         }
285     }
286 
287     void test16() {
288         MyValue4 val = new MyValue4();
289         for (int i = 0; i < 10; ++i) {
290             for (int j = 0; j < 10; ++j) {
291                 val = (new MyValue4Wrapper(val)).val;
292                 for (int k = 0; k < 10; ++k) {
293                 }
294             }
295         }
296     }
297 
298     static MyValue6 test17Field = new MyValue6();
299 
300     void test17() {
301         for (int i = 0; i < 10; ++i) {
302             MyValue6 val = new MyValue6();
303             for (int j = 0; j < 10; ++j) {
304                 test17Field = val;
305             }
306         }
307     }
308 
309     EmptyValue test18Field;
310 
311     EmptyValue test18() {
312         EmptyValue val = new EmptyValue();
313         test18Field = val;
314         return test18Field;
315     }
316 
317     @NullRestricted
318     MyValue1 test19Field = new MyValue1();
319 
320     public void test19() {
321         for (int i = 0; i < 10; ++i) {
322             MyValue1 val = new MyValue1();
323             for (int j = 0; j < 10; ++j)
324                 test19Field = val;
325         }
326     }
327 
328     public static void main(String[] args) {
329         TestGenerated t = new TestGenerated();
330         EmptyPrimitive[] array1 = (EmptyPrimitive[])ValueClass.newNullRestrictedArray(EmptyPrimitive.class, 1);
331         MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10);
332         MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
333         array3[0] = new MyValue1();
334         MyValue3[] array4 = (MyValue3[])ValueClass.newNullRestrictedArray(MyValue3.class, 1);
335         array4[0] = new MyValue3();
336         MyValue5[] array5 = (MyValue5[])ValueClass.newNullRestrictedArray(MyValue5.class, 1);
337         array5[0] = new MyValue5();
338         array4[0].intArray[0] = 42;
339 
340         for (int i = 0; i < 50_000; ++i) {
341             t.test1(array1);
342             t.test2(array2);
343             t.test3(array2);
344             t.test4(array3);
345             t.test5(array3);
346             t.test6();
347             t.test7(false);
348             t.test8(array3);
349             t.test9(true);
350             t.test10(array4);
351             t.test11(array4);
352             t.test12();
353             t.test13(array5);
354             t.test14(false, new MyValue4());
355             t.test15();
356             // TODO 8332814 This triggers the "nothing between inner and outer loop" assert
357             // t.test16();
358             t.test17();
359             t.test18();
360             t.test19();
361         }
362     }
363 }