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 
 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     @CodeReflection
 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     @CodeReflection
 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     @CodeReflection
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     @CodeReflection
165     @IR("""
166             func @"test4" (%0 : java.type:"TryTest")java.type:"void" -> {
167                 java.try
168                     ()Tuple<Var<java.type:"TryTest$A">, java.type:"TryTest$B", Var<java.type:"TryTest$C">> -> {
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                         %3 : java.type:"TryTest$A" = var.load %2;
172                         %4 : java.type:"TryTest$B" = field.load %3 @java.ref:"TryTest$A::b:TryTest$B";
173                         %5 : java.type:"TryTest$A" = var.load %2;
174                         %6 : java.type:"TryTest$B" = field.load %5 @java.ref:"TryTest$A::b:TryTest$B";
175                         %7 : java.type:"TryTest$C" = field.load %6 @java.ref:"TryTest$B::c:TryTest$C";
176                         %8 : Var<java.type:"TryTest$C"> = var %7 @"c";
177                         %9 : Tuple<Var<java.type:"TryTest$A">, java.type:"TryTest$B", Var<java.type:"TryTest$C">> = tuple %2 %4 %8;
178                         yield %9;
179                     }
180                     (%10 : Var<java.type:"TryTest$A">, %11 : Var<java.type:"TryTest$C">)java.type:"void" -> {
181                         %12 : java.type:"TryTest$A" = var.load %10;
182                         %13 : Var<java.type:"TryTest$A"> = var %12 @"_a";
183                         %14 : java.type:"TryTest$C" = var.load %11;
184                         %15 : Var<java.type:"TryTest$C"> = var %14 @"_c";
185                         yield;
186                     }
187                     (%16 : java.type:"java.lang.Throwable")java.type:"void" -> {
188                         %17 : Var<java.type:"java.lang.Throwable"> = var %16 @"t";
189                         %18 : java.type:"java.lang.Throwable" = var.load %17;
190                         invoke %18 @java.ref:"java.lang.Throwable::printStackTrace():void";
191                         yield;
192                     }
193                     ()java.type:"void" -> {
194                         %19 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
195                         %20 : java.type:"java.lang.String" = constant @"F";
196                         invoke %19 %20 @java.ref:"java.io.PrintStream::println(java.lang.String):void";
197                         yield;
198                     };
199                 return;
200             };
201             """)
202     void test4() throws Exception {
203         try (A a = a(); a.b; C c = a.b.c) {
204             A _a = a;
205             C _c = c;
206         } catch (Throwable t) {
207             t.printStackTrace();
208         } finally {
209             System.out.println("F");
210         }
211     }
212 
213     @CodeReflection
214     @IR("""
215             func @"test5" (%0 : java.type:"TryTest")java.type:"void" -> {
216                 %1 : java.type:"int" = constant @0;
217                 %2 : Var<java.type:"int"> = var %1 @"i";
218                 java.try
219                     ()java.type:"void" -> {
220                         %3 : java.type:"int" = constant @1;
221                         var.store %2 %3;
222                         yield;
223                     }
224                     (%4 : java.type:"java.lang.NullPointerException")java.type:"void" -> {
225                         %5 : Var<java.type:"java.lang.NullPointerException"> = var %4 @"e";
226                         %6 : java.type:"int" = constant @2;
227                         var.store %2 %6;
228                         yield;
229                     }
230                     (%7 : java.type:"java.lang.OutOfMemoryError")java.type:"void" -> {
231                         %8 : Var<java.type:"java.lang.OutOfMemoryError"> = var %7 @"e";
232                         %9 : java.type:"int" = constant @3;
233                         var.store %2 %9;
234                         yield;
235                     };
236                 return;
237             };
238             """)
239     void test5() {
240         int i = 0;
241         try {
242             i = 1;
243         } catch (NullPointerException e) {
244             i = 2;
245         } catch (OutOfMemoryError e) {
246             i = 3;
247         }
248     }
249 
250     @CodeReflection
251     @IR("""
252             func @"test6" (%0 : java.type:"TryTest")java.type:"void" -> {
253                 %1 : java.type:"int" = constant @0;
254                 %2 : Var<java.type:"int"> = var %1 @"i";
255                 java.try
256                     ()java.type:"void" -> {
257                         return;
258                     }
259                     (%3 : java.type:"java.lang.Exception")java.type:"void" -> {
260                         %4 : Var<java.type:"java.lang.Exception"> = var %3 @"e";
261                         %5 : java.type:"java.lang.Exception" = var.load %4;
262                         throw %5;
263                     }
264                     ()java.type:"void" -> {
265                         return;
266                     };
267                 unreachable;
268             };
269             """)
270     void test6() {
271         int i = 0;
272         try {
273             return;
274         } catch (Exception e) {
275             throw e;
276         } finally {
277             return;
278         }
279      }
280 
281 }