1 /*
  2  * Copyright (c) 2018, 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 package runtime.valhalla.inlinetypes;
 24 
 25 
 26 import jdk.test.lib.Asserts;
 27 import jdk.internal.vm.annotation.LooselyConsistentValue;
 28 import jdk.internal.vm.annotation.NullRestricted;
 29 import jdk.internal.vm.annotation.Strict;
 30 
 31 
 32 /*
 33  * @test
 34  * @summary Flattenable field semantic test
 35  * @library /test/lib
 36  * @modules java.base/jdk.internal.vm.annotation
 37  * @enablePreview
 38  * @compile FlattenableSemanticTest.java
 39  * @run main/othervm -XX:+UseFieldFlattening runtime.valhalla.inlinetypes.FlattenableSemanticTest
 40  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:ForceNonTearable=* runtime.valhalla.inlinetypes.FlattenableSemanticTest
 41  */
 42 public class FlattenableSemanticTest {
 43 
 44     @LooselyConsistentValue
 45     static value class Point {
 46         final int x = 0;
 47         final int y = 0;
 48     }
 49 
 50     @LooselyConsistentValue
 51     public static value class JumboInline {
 52         final long l0 = 0;
 53         final long l1 = 1;
 54         final long l2 = 2;
 55         final long l3 = 3;
 56         final long l4 = 4;
 57         final long l5 = 5;
 58         final long l6 = 6;
 59         final long l7 = 7;
 60         final long l8 = 8;
 61         final long l9 = 9;
 62         final long l10 = 10;
 63         final long l11 = 11;
 64         final long l12 = 12;
 65         final long l13 = 13;
 66         final long l14 = 14;
 67         final long l15 = 15;
 68         final long l16 = 16;
 69         final long l17 = 17;
 70         final long l18 = 18;
 71         final long l19 = 19;
 72     }
 73 
 74     static Point nfsp;
 75     @Strict
 76     @NullRestricted
 77     static Point fsp = new Point();
 78 
 79     Point nfip;
 80     @Strict
 81     @NullRestricted
 82     Point fip;
 83 
 84     static JumboInline nfsj;
 85     @Strict
 86     @NullRestricted
 87     static JumboInline fsj = new JumboInline();
 88 
 89     JumboInline nfij;
 90     @Strict
 91     @NullRestricted
 92     JumboInline fij;
 93 
 94     static Object getNull() {
 95         return null;
 96     }
 97 
 98     FlattenableSemanticTest() {
 99         fip = new Point();
100         fij = new JumboInline();
101     }
102 
103     public static void main(String[] args) {
104         FlattenableSemanticTest test = new FlattenableSemanticTest();
105 
106         // Uninitialized inline fields must be null for non flattenable fields
107         Asserts.assertNull(nfsp, "Invalid non null value for uninitialized non flattenable field");
108         Asserts.assertNull(nfsj, "Invalid non null value for uninitialized non flattenable field");
109         Asserts.assertNull(test.nfip, "Invalid non null value for uninitialized non flattenable field");
110         Asserts.assertNull(test.nfij, "Invalid non null value for uninitialized non flattenable field");
111 
112         // fsp.equals(null);
113 
114         // Uninitialized inline fields must be non null for flattenable fields
115         Asserts.assertNotNull(fsp, "Invalid null value for uninitialized flattenable field");
116         Asserts.assertNotNull(fsj, "Invalid null value for uninitialized flattenable field");
117         Asserts.assertNotNull(test.fip, "Invalid null value for uninitialized flattenable field");
118         Asserts.assertNotNull(test.fij, "Invalid null value for uninitialized flattenable field");
119 
120         // Assigning null must be allowed for non flattenable inline fields
121         boolean exception = true;
122         try {
123             nfsp = (Point)getNull();
124             nfsp = null;
125             exception = false;
126         } catch (NullPointerException e) {
127             exception = true;
128         }
129         Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
130 
131         try {
132             nfsj = (JumboInline)getNull();
133             nfsj = null;
134             exception = false;
135         } catch (NullPointerException e) {
136             exception = true;
137         }
138         Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
139 
140         try {
141             test.nfip = (Point)getNull();
142             test.nfip = null;
143             exception = false;
144         } catch (NullPointerException e) {
145             exception = true;
146         }
147         Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
148 
149         try {
150             test.nfij = (JumboInline)getNull();
151             test.nfij = null;
152             exception = false;
153         } catch (NullPointerException e) {
154             exception = true;
155         }
156         Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
157 
158         // Assigning null to a flattenable inline field must trigger a NPE
159         exception = false;
160         try {
161             fsp = (Point)getNull();
162         } catch(NullPointerException e) {
163             exception = true;
164         }
165         Asserts.assertTrue(exception, "NPE not thrown when assigning null to a flattenable field");
166         exception = false;
167         try {
168             fsj = (JumboInline)getNull();
169         } catch(NullPointerException e) {
170             exception = true;
171         }
172         Asserts.assertTrue(exception, "NPE not thrown when assigning null to a flattenable field");
173         exception = false;
174         try {
175             test.fip = (Point)getNull();
176         } catch(NullPointerException e) {
177             exception = true;
178         }
179         Asserts.assertTrue(exception, "NPE not thrown when assigning null to a flattenable field");
180         exception = false;
181         try {
182             test.fij = (JumboInline)getNull();
183         } catch(NullPointerException e) {
184             exception = true;
185         }
186         Asserts.assertTrue(exception, "NPE not thrown when assigning null to a flattenable field");
187         exception = false;
188     }
189 
190 }