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