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