1 /*
  2  * Copyright (c) 2024, 2026, 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.Reflect;
 25 
 26 /*
 27  * @test
 28  * @summary Smoke test for code reflection with try statements.
 29  * @modules jdk.incubator.code
 30  * @build TryTest
 31  * @build CodeReflectionTester
 32  * @run main CodeReflectionTester TryTest
 33  */
 34 
 35 public class TryTest {
 36 
 37     @Reflect
 38     @IR("""
 39             func @"test1" (%0 : java.type:"TryTest")java.type:"void" -> {
 40                 %1 : java.type:"int" = constant @0;
 41                 %2 : Var<java.type:"int"> = var %1 @"i";
 42                 java.try
 43                     ()java.type:"void" -> {
 44                         %3 : java.type:"int" = constant @1;
 45                         var.store %2 %3;
 46                         yield;
 47                     }
 48                     (%4 : java.type:"java.lang.Exception")java.type:"void" -> {
 49                         %5 : Var<java.type:"java.lang.Exception"> = var %4 @"e";
 50                         %6 : java.type:"int" = constant @2;
 51                         var.store %2 %6;
 52                         yield;
 53                     }
 54                     ()java.type:"void" -> {
 55                         %7 : java.type:"int" = constant @3;
 56                         var.store %2 %7;
 57                         yield;
 58                     };
 59                 return;
 60             };
 61             """)
 62     void test1() {
 63         int i = 0;
 64         try {
 65             i = 1;
 66         } catch (Exception e) {
 67             i = 2;
 68         } finally {
 69             i = 3;
 70         }
 71     }
 72 
 73     @Reflect
 74     @IR("""
 75             func @"test2" (%0 : java.type:"TryTest")java.type:"void" -> {
 76                 %1 : java.type:"int" = constant @0;
 77                 %2 : Var<java.type:"int"> = var %1 @"i";
 78                 java.try
 79                     ()java.type:"void" -> {
 80                         %3 : java.type:"int" = constant @1;
 81                         var.store %2 %3;
 82                         yield;
 83                     }
 84                     ()java.type:"void" -> {
 85                         %4 : java.type:"int" = constant @3;
 86                         var.store %2 %4;
 87                         yield;
 88                     };
 89                 return;
 90             };
 91             """)
 92     void test2() {
 93         int i = 0;
 94         try {
 95             i = 1;
 96         } finally {
 97             i = 3;
 98         }
 99     }
100 
101     @Reflect
102     @IR("""
103             func @"test3" (%0 : java.type:"TryTest")java.type:"void" -> {
104                 %1 : java.type:"int" = constant @0;
105                 %2 : Var<java.type:"int"> = var %1 @"i";
106                 java.try
107                     ()java.type:"void" -> {
108                         %3 : java.type:"int" = constant @1;
109                         var.store %2 %3;
110                         yield;
111                     }
112                     (%4 : java.type:"java.lang.Exception")java.type:"void" -> {
113                         %5 : Var<java.type:"java.lang.Exception"> = var %4 @"e";
114                         %6 : java.type:"java.lang.Exception" = var.load %5;
115                         invoke %6 @java.ref:"java.lang.Exception::printStackTrace():void";
116                         yield;
117                     };
118                 return;
119             };
120             """)
121     void test3() {
122         int i = 0;
123         try {
124             i = 1;
125         } catch (Exception e) {
126             e.printStackTrace();
127         }
128     }
129 
130 
131     static class A implements AutoCloseable {
132         final B b;
133 
134         public A() {
135             this.b = null;
136         }
137 
138         @Override
139         public void close() throws Exception {
140 
141         }
142     }
143 
144     static class B implements AutoCloseable {
145         C c;
146 
147         @Override
148         public void close() throws Exception {
149 
150         }
151     }
152 
153     static class C implements AutoCloseable {
154         @Override
155         public void close() throws Exception {
156 
157         }
158     }
159 
160     A a() {
161         return null;
162     }
163 
164     @Reflect
165     @IR("""
166             func @"test4" (%0 : java.type:"TryTest")java.type:"void" -> {
167                 java.try
168                     ()Var<java.type:"TryTest$A"> -> {
169                         %1 : java.type:"TryTest$A" = invoke %0 @java.ref:"TryTest::a():TryTest$A";
170                         %2 : Var<java.type:"TryTest$A"> = var %1 @"a";
171                         yield %2;
172                     }
173                     (%3 : Var<java.type:"TryTest$A">)java.type:"TryTest$B" -> {
174                         %4 : java.type:"TryTest$A" = var.load %3;
175                         %5 : java.type:"TryTest$B" = field.load %4 @java.ref:"TryTest$A::b:TryTest$B";
176                         yield %5;
177                     }
178                     (%6 : Var<java.type:"TryTest$A">, %7 : java.type:"TryTest$B")Var<java.type:"TryTest$C"> -> {
179                         %8 : java.type:"TryTest$A" = var.load %6;
180                         %9 : java.type:"TryTest$B" = field.load %8 @java.ref:"TryTest$A::b:TryTest$B";
181                         %10 : java.type:"TryTest$C" = field.load %9 @java.ref:"TryTest$B::c:TryTest$C";
182                         %11 : Var<java.type:"TryTest$C"> = var %10 @"c";
183                         yield %11;
184                     }
185                     (%12 : Var<java.type:"TryTest$A">, %13 : java.type:"TryTest$B", %14 : Var<java.type:"TryTest$C">)java.type:"void" -> {
186                         %15 : java.type:"TryTest$A" = var.load %12;
187                         %16 : Var<java.type:"TryTest$A"> = var %15 @"_a";
188                         %17 : java.type:"TryTest$C" = var.load %14;
189                         %18 : Var<java.type:"TryTest$C"> = var %17 @"_c";
190                         yield;
191                     }
192                     (%19 : java.type:"java.lang.Throwable")java.type:"void" -> {
193                         %20 : Var<java.type:"java.lang.Throwable"> = var %19 @"t";
194                         %21 : java.type:"java.lang.Throwable" = var.load %20;
195                         invoke %21 @java.ref:"java.lang.Throwable::printStackTrace():void";
196                         yield;
197                     }
198                     ()java.type:"void" -> {
199                         %22 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
200                         %23 : java.type:"java.lang.String" = constant @"F";
201                         invoke %22 %23 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
202                         yield;
203                     };
204                 return;
205             };
206             """)
207     void test4() throws Exception {
208         try (A a = a(); a.b; C c = a.b.c) {
209             A _a = a;
210             C _c = c;
211         } catch (Throwable t) {
212             t.printStackTrace();
213         } finally {
214             System.out.println("F");
215         }
216     }
217 
218     @Reflect
219     @IR("""
220             func @"test5" (%0 : java.type:"TryTest")java.type:"void" -> {
221                 %1 : java.type:"int" = constant @0;
222                 %2 : Var<java.type:"int"> = var %1 @"i";
223                 java.try
224                     ()java.type:"void" -> {
225                         %3 : java.type:"int" = constant @1;
226                         var.store %2 %3;
227                         yield;
228                     }
229                     (%4 : java.type:"java.lang.NullPointerException")java.type:"void" -> {
230                         %5 : Var<java.type:"java.lang.NullPointerException"> = var %4 @"e";
231                         %6 : java.type:"int" = constant @2;
232                         var.store %2 %6;
233                         yield;
234                     }
235                     (%7 : java.type:"java.lang.OutOfMemoryError")java.type:"void" -> {
236                         %8 : Var<java.type:"java.lang.OutOfMemoryError"> = var %7 @"e";
237                         %9 : java.type:"int" = constant @3;
238                         var.store %2 %9;
239                         yield;
240                     };
241                 return;
242             };
243             """)
244     void test5() {
245         int i = 0;
246         try {
247             i = 1;
248         } catch (NullPointerException e) {
249             i = 2;
250         } catch (OutOfMemoryError e) {
251             i = 3;
252         }
253     }
254 
255     @Reflect
256     @IR("""
257             func @"test6" (%0 : java.type:"TryTest")java.type:"void" -> {
258                 %1 : java.type:"int" = constant @0;
259                 %2 : Var<java.type:"int"> = var %1 @"i";
260                 java.try
261                     ()java.type:"void" -> {
262                         return;
263                     }
264                     (%3 : java.type:"java.lang.Exception")java.type:"void" -> {
265                         %4 : Var<java.type:"java.lang.Exception"> = var %3 @"e";
266                         %5 : java.type:"java.lang.Exception" = var.load %4;
267                         throw %5;
268                     }
269                     ()java.type:"void" -> {
270                         return;
271                     };
272                 unreachable;
273             };
274             """)
275     void test6() {
276         int i = 0;
277         try {
278             return;
279         } catch (Exception e) {
280             throw e;
281         } finally {
282             return;
283         }
284      }
285 
286 }