1 /*
  2  * Copyright (c) 2018, 2021, 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 TestFieldNullability
 26  * @library /test/lib
 27  * @compile -XDallowWithFieldOperator TestFieldNullability.java
 28  * @run main/othervm -Xmx128m -XX:InlineFieldMaxFlatSize=32
 29  *                   runtime.valhalla.inlinetypes.TestFieldNullability
 30  */
 31 
 32 package runtime.valhalla.inlinetypes;
 33 
 34 import jdk.test.lib.Asserts;
 35 
 36 public class TestFieldNullability {
 37     static primitive class MyValue {
 38         int x;
 39 
 40         public MyValue() {
 41             x = 314;
 42         }
 43     }
 44 
 45     static primitive class MyBigValue {
 46         long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9;
 47         long l10, l11, l12, l13, l14, l15, l16, l17, l18, l19;
 48 
 49         public MyBigValue() {
 50             l0 = l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = l9 = 271;
 51             l10 = l11 = l12 = l13 = l14 = l15 = l16 = l17 = l18 = l19 = 271;
 52         }
 53     }
 54 
 55     static primitive class TestInlineType {
 56         final MyValue.ref nullableField;
 57         final MyValue nullfreeField;        // flattened
 58         final MyValue.ref nullField;           // src of null
 59         final MyBigValue nullfreeBigField;  // not flattened
 60         final MyBigValue.ref nullBigField;     // src of null
 61 
 62         public void test() {
 63             Asserts.assertNull(nullField, "Invalid non null value for uninitialized non flattenable field");
 64             Asserts.assertNull(nullBigField, "Invalid non null value for uninitialized non flattenable field");
 65             boolean NPE = false;
 66             try {
 67                 TestInlineType tv = __WithField(this.nullableField, nullField);
 68             } catch(NullPointerException e) {
 69                 NPE = true;
 70             }
 71             Asserts.assertFalse(NPE, "Invalid NPE when assigning null to a non flattenable field");
 72             try {
 73                 TestInlineType tv = __WithField(this.nullfreeField, (MyValue) nullField);
 74             } catch(NullPointerException e) {
 75                 NPE = true;
 76             }
 77             Asserts.assertTrue(NPE, "Missing NPE when assigning null to a flattened field");
 78             try {
 79                 TestInlineType tv = __WithField(this.nullfreeBigField, (MyBigValue) nullBigField);
 80             } catch(NullPointerException e) {
 81                 NPE = true;
 82             }
 83             Asserts.assertTrue(NPE, "Missing NPE when assigning null to a flattenable field");
 84         }
 85 
 86         public TestInlineType() {
 87             nullableField = MyValue.default;
 88             nullfreeField = MyValue.default;
 89             nullField = MyValue.default;           // fake assignment
 90             nullfreeBigField = MyBigValue.default;
 91             nullBigField = MyBigValue.default;     // fake assignment
 92 
 93         }
 94     }
 95 
 96     static class TestClass {
 97         MyValue.ref nullableField;
 98         MyValue nullfreeField;       // flattened
 99         MyValue.ref nullField;
100         MyBigValue nullfreeBigField; // not flattened
101         MyBigValue.ref nullBigField;
102 
103         public void test() {
104             Asserts.assertNull(nullField, "Invalid non null value for uninitialized non flattenable field");
105             Asserts.assertNull(nullBigField, "Invalid non null value for uninitialized non flattenable field");
106             boolean NPE = false;
107             try {
108                 nullableField = nullField;
109             } catch(NullPointerException e) {
110                 NPE = true;
111             }
112             Asserts.assertFalse(NPE, "Invalid NPE when assigning null to a non flattenable field");
113             try {
114                 this.nullfreeField = (MyValue) nullField;
115             } catch(NullPointerException e) {
116                 NPE = true;
117             }
118             Asserts.assertTrue(NPE, "Missing NPE when assigning null to a flattened field");
119             try {
120                 this.nullfreeBigField = (MyBigValue) nullBigField;
121             } catch(NullPointerException e) {
122                 NPE = true;
123             }
124             Asserts.assertTrue(NPE, "Missing NPE when assigning null to a flattenable field");
125         }
126     }
127 
128     public static void main(String[] args) {
129         TestClass tc = new TestClass();
130         tc.test();
131         TestInlineType tv =
132             TestInlineType.default;
133         tv.test();
134     }
135 
136 }