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" ()void -> { 41 %0 : java.lang.Number = constant @null; 42 %1 : java.lang.Number = invoke %0 @"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" ()void -> { 53 %0 : int = constant @"1"; 54 %1 : java.lang.Integer = invoke %0 @"java.lang.Integer::valueOf(int)java.lang.Integer"; 55 %2 : double = constant @"3.0"; 56 %3 : java.lang.Double = invoke %2 @"java.lang.Double::valueOf(double)java.lang.Double"; 57 %4 : java.util.List<+<java.lang.Number>> = invoke %1 %3 @"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" ()void -> { 70 %0 : java.lang.RuntimeException = constant @null; 71 %1 : java.lang.RuntimeException = invoke %0 @"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" ()void -> { 89 %0 : java.lang.Object = constant @null; 90 %1 : DenotableTypesTest$C = cast %0 @"DenotableTypesTest$C"; 91 %2 : java.lang.Object = constant @null; 92 %3 : DenotableTypesTest$D = cast %2 @"DenotableTypesTest$D"; 93 %4 : DenotableTypesTest$A = invoke %1 %3 @"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" ()void -> { 104 %0 : java.util.List<+<java.lang.Number>> = constant @null; 105 %1 : Var<java.util.List<+<java.lang.Number>>> = var %0 @"l"; 106 %2 : java.util.List<+<java.lang.Number>> = var.load %1; 107 %3 : int = constant @"0"; 108 %4 : java.lang.Number = invoke %2 %3 @"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" ()void -> { 120 %0 : java.util.List<-<java.lang.Number>> = constant @null; 121 %1 : Var<java.util.List<-<java.lang.Number>>> = var %0 @"l"; 122 %2 : java.util.List<-<java.lang.Number>> = var.load %1; 123 %3 : int = constant @"0"; 124 %4 : java.lang.Object = invoke %2 %3 @"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" ()void -> { 138 %0 : #DenotableTypesTest::test7()void::X<java.lang.Object> = constant @null; 139 %1 : Var<#DenotableTypesTest::test7()void::X<java.lang.Object>> = var %0 @"x"; 140 %2 : #DenotableTypesTest::test7()void::X<java.lang.Object> = var.load %1; 141 %3 : java.lang.Runnable = cast %2 @"java.lang.Runnable"; 142 invoke %3 @"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.util.List<+<DenotableTypesTest$Adder<java.lang.Integer>>>)void -> { 158 %1 : Var<java.util.List<+<DenotableTypesTest$Adder<java.lang.Integer>>>> = var %0 @"list"; 159 %2 : java.util.List<+<DenotableTypesTest$Adder<java.lang.Integer>>> = var.load %1; 160 %3 : int = constant @"0"; 161 %4 : DenotableTypesTest$Adder<java.lang.Integer> = invoke %2 %3 @"java.util.List::get(int)java.lang.Object"; 162 %5 : java.util.List<+<DenotableTypesTest$Adder<java.lang.Integer>>> = var.load %1; 163 %6 : int = constant @"1"; 164 %7 : DenotableTypesTest$Adder<java.lang.Integer> = invoke %5 %6 @"java.util.List::get(int)java.lang.Object"; 165 invoke %4 %7 @"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.util.List<+<DenotableTypesTest$Box<java.lang.Integer>>>)void -> { 180 %1 : Var<java.util.List<+<DenotableTypesTest$Box<java.lang.Integer>>>> = var %0 @"list"; 181 %2 : java.util.List<+<DenotableTypesTest$Box<java.lang.Integer>>> = var.load %1; 182 %3 : int = constant @"0"; 183 %4 : DenotableTypesTest$Box<java.lang.Integer> = invoke %2 %3 @"java.util.List::get(int)java.lang.Object"; 184 %5 : java.lang.Integer = field.load %4 @"DenotableTypesTest$Box::x()java.lang.Object"; 185 %6 : Var<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" ()void -> { 210 java.try 211 ()void -> { 212 invoke @"DenotableTypesTest::g()void"; 213 yield; 214 } 215 (%0 : java.lang.Exception)void -> { 216 %1 : Var<java.lang.Exception> = var %0 @"x"; 217 %2 : java.lang.Exception = var.load %1; 218 %3 : DenotableTypesTest$E = cast %2 @"DenotableTypesTest$E"; 219 invoke %3 @"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 }