1 /* 2 * Copyright (c) 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 import jdk.incubator.code.CodeReflection; 25 import java.util.List; 26 27 /* 28 * @test 29 * @summary Smoke test for non-denotable types in IR type descriptors 30 * @modules jdk.incubator.code 31 * @build DenotableTypesTest 32 * @build CodeReflectionTester 33 * @run main CodeReflectionTester DenotableTypesTest 34 */ 35 36 public class DenotableTypesTest { 37 static <X extends Number & Runnable> X m1(X x) { return null; } 38 @CodeReflection 39 @IR(""" 40 func @"test1" ()java.type:"void" -> { 41 %0 : java.type:"java.lang.Number" = constant @null; 42 %1 : java.type:"java.lang.Number" = invoke %0 @java.ref:"DenotableTypesTest::m1(java.lang.Number):java.lang.Number"; 43 return; 44 }; 45 """) 46 static void test1() { 47 m1(null); 48 } 49 50 @CodeReflection 51 @IR(""" 52 func @"test2" ()java.type:"void" -> { 53 %0 : java.type:"int" = constant @1; 54 %1 : java.type:"java.lang.Integer" = invoke %0 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer"; 55 %2 : java.type:"double" = constant @3.0d; 56 %3 : java.type:"java.lang.Double" = invoke %2 @java.ref:"java.lang.Double::valueOf(double):java.lang.Double"; 57 %4 : java.type:"java.util.List<? extends java.lang.Number>" = invoke %1 %3 @java.ref:"java.util.List::of(java.lang.Object, java.lang.Object):java.util.List"; 58 return; 59 }; 60 """) 61 static void test2() { 62 List.of(1, 3d); // infinite type! (List<Object & Serializable & Comparable<...>>) 63 } 64 65 static <X extends Throwable> X m2(X x) throws X { return null; } 66 67 @CodeReflection 68 @IR(""" 69 func @"test3" ()java.type:"void" -> { 70 %0 : java.type:"java.lang.RuntimeException" = constant @null; 71 %1 : java.type:"java.lang.RuntimeException" = invoke %0 @java.ref:"DenotableTypesTest::m2(java.lang.Throwable):java.lang.Throwable"; 72 return; 73 }; 74 """) 75 static void test3() { // @@@ cast? 76 m2(null); 77 } 78 79 interface A { } 80 interface B { } 81 static class C implements A, B { } 82 static class D implements A, B { } 83 84 static <Z> Z pick(Z z1, Z z2) { return null; } 85 86 @CodeReflection 87 @IR(""" 88 func @"test4" ()java.type:"void" -> { 89 %0 : java.type:"java.lang.Object" = constant @null; 90 %1 : java.type:"DenotableTypesTest$C" = cast %0 @java.type:"DenotableTypesTest$C"; 91 %2 : java.type:"java.lang.Object" = constant @null; 92 %3 : java.type:"DenotableTypesTest$D" = cast %2 @java.type:"DenotableTypesTest$D"; 93 %4 : java.type:"DenotableTypesTest$A" = invoke %1 %3 @java.ref:"DenotableTypesTest::pick(java.lang.Object, java.lang.Object):java.lang.Object"; 94 return; 95 }; 96 """) 97 static void test4() { // @@@ cast? 98 pick((C)null, (D)null); 99 } 100 101 @CodeReflection 102 @IR(""" 103 func @"test5" ()java.type:"void" -> { 104 %0 : java.type:"java.util.List<? extends java.lang.Number>" = constant @null; 105 %1 : Var<java.type:"java.util.List<? extends java.lang.Number>"> = var %0 @"l"; 106 %2 : java.type:"java.util.List<? extends java.lang.Number>" = var.load %1; 107 %3 : java.type:"int" = constant @0; 108 %4 : java.type:"java.lang.Number" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object"; 109 return; 110 }; 111 """) 112 static void test5() { // @@@ cast? 113 List<? extends Number> l = null; 114 l.get(0); 115 } 116 117 @CodeReflection 118 @IR(""" 119 func @"test6" ()java.type:"void" -> { 120 %0 : java.type:"java.util.List<? super java.lang.Number>" = constant @null; 121 %1 : Var<java.type:"java.util.List<? super java.lang.Number>"> = var %0 @"l"; 122 %2 : java.type:"java.util.List<? super java.lang.Number>" = var.load %1; 123 %3 : java.type:"int" = constant @0; 124 %4 : java.type:"java.lang.Object" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object"; 125 return; 126 }; 127 """) 128 static void test6() { 129 List<? super Number> l = null; 130 l.get(0); 131 } 132 133 static void consume(Runnable r) { } 134 135 @CodeReflection 136 @IR(""" 137 func @"test7" ()java.type:"void" -> { 138 %0 : java.type:"&DenotableTypesTest::test7():void::<X>" = constant @null; 139 %1 : Var<java.type:"&DenotableTypesTest::test7():void::<X>"> = var %0 @"x"; 140 %2 : java.type:"&DenotableTypesTest::test7():void::<X>" = var.load %1; 141 %3 : java.type:"java.lang.Runnable" = cast %2 @java.type:"java.lang.Runnable"; 142 invoke %3 @java.ref:"DenotableTypesTest::consume(java.lang.Runnable):void"; 143 return; 144 }; 145 """) 146 static <X extends Object & Runnable> void test7() { 147 X x = null; 148 consume(x); 149 } 150 151 interface Adder<X> { 152 void add(Adder<X> adder); 153 } 154 155 @CodeReflection 156 @IR(""" 157 func @"test8" (%0 : java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>")java.type:"void" -> { 158 %1 : Var<java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>"> = var %0 @"list"; 159 %2 : java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>" = var.load %1; 160 %3 : java.type:"int" = constant @0; 161 %4 : java.type:"DenotableTypesTest$Adder<java.lang.Integer>" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object"; 162 %5 : java.type:"java.util.List<? extends DenotableTypesTest$Adder<java.lang.Integer>>" = var.load %1; 163 %6 : java.type:"int" = constant @1; 164 %7 : java.type:"DenotableTypesTest$Adder<java.lang.Integer>" = invoke %5 %6 @java.ref:"java.util.List::get(int):java.lang.Object"; 165 invoke %4 %7 @java.ref:"DenotableTypesTest$Adder::add(DenotableTypesTest$Adder):void"; 166 return; 167 }; 168 """) 169 static void test8(List<? extends Adder<Integer>> list) { 170 list.get(0).add(list.get(1)); 171 } 172 173 static class Box<X> { 174 X x; 175 } 176 177 @CodeReflection 178 @IR(""" 179 func @"test9" (%0 : java.type:"java.util.List<? extends DenotableTypesTest$Box<java.lang.Integer>>")java.type:"void" -> { 180 %1 : Var<java.type:"java.util.List<? extends DenotableTypesTest$Box<java.lang.Integer>>"> = var %0 @"list"; 181 %2 : java.type:"java.util.List<? extends DenotableTypesTest$Box<java.lang.Integer>>" = var.load %1; 182 %3 : java.type:"int" = constant @0; 183 %4 : java.type:"DenotableTypesTest$Box<java.lang.Integer>" = invoke %2 %3 @java.ref:"java.util.List::get(int):java.lang.Object"; 184 %5 : java.type:"java.lang.Integer" = field.load %4 @java.ref:"DenotableTypesTest$Box::x:java.lang.Object"; 185 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i"; 186 return; 187 }; 188 """) 189 static void test9(List<? extends Box<Integer>> list) { 190 Integer i = list.get(0).x; 191 } 192 193 interface E { 194 void m(); 195 } 196 197 static class XA extends Exception implements E { 198 public void m() { } 199 } 200 201 static class XB extends Exception implements E { 202 public void m() { } 203 } 204 205 static void g() throws XA, XB { } 206 207 @CodeReflection 208 @IR(""" 209 func @"test10" ()java.type:"void" -> { 210 java.try 211 ()java.type:"void" -> { 212 invoke @java.ref:"DenotableTypesTest::g():void"; 213 yield; 214 } 215 (%0 : java.type:"java.lang.Exception")java.type:"void" -> { 216 %1 : Var<java.type:"java.lang.Exception"> = var %0 @"x"; 217 %2 : java.type:"java.lang.Exception" = var.load %1; 218 %3 : java.type:"DenotableTypesTest$E" = cast %2 @java.type:"DenotableTypesTest$E"; 219 invoke %3 @java.ref:"DenotableTypesTest$E::m():void"; 220 yield; 221 }; 222 return; 223 }; 224 """) 225 static void test10() { 226 try { 227 g(); 228 } catch (XA | XB x) { 229 x.m(); 230 } 231 } 232 }