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 }