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