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 : TryTest)void -> {
 40                 %1 : int = constant @"0";
 41                 %2 : Var<int> = var %1 @"i";
 42                 java.try
 43                     ()void -> {
 44                         %3 : int = constant @"1";
 45                         var.store %2 %3;
 46                         yield;
 47                     }
 48                     ^catch(%4 : java.lang.Exception)void -> {
 49                         %5 : Var<java.lang.Exception> = var %4 @"e";
 50                         %6 : int = constant @"2";
 51                         var.store %2 %6;
 52                         yield;
 53                     }
 54                     ^finally()void -> {
 55                         %7 : 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 : TryTest)void -> {
 76                 %1 : int = constant @"0";
 77                 %2 : Var<int> = var %1 @"i";
 78                 java.try
 79                     ()void -> {
 80                         %3 : int = constant @"1";
 81                         var.store %2 %3;
 82                         yield;
 83                     }
 84                     ^finally()void -> {
 85                         %4 : 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 : TryTest)void -> {
104                 %1 : int = constant @"0";
105                 %2 : Var<int> = var %1 @"i";
106                 java.try
107                     ()void -> {
108                         %3 : int = constant @"1";
109                         var.store %2 %3;
110                         yield;
111                     }
112                     ^catch(%4 : java.lang.Exception)void -> {
113                         %5 : Var<java.lang.Exception> = var %4 @"e";
114                         %6 : java.lang.Exception = var.load %5;
115                         invoke %6 @"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 : TryTest)void -> {
167                 java.try
168                     ^resources()Tuple<Var<TryTest$A>, TryTest$B, Var<TryTest$C>> -> {
169                         %1 : TryTest$A = invoke %0 @"TryTest::a()TryTest$A";
170                         %2 : Var<TryTest$A> = var %1 @"a";
171                         %3 : TryTest$A = var.load %2;
172                         %4 : TryTest$B = field.load %3 @"TryTest$A::b()TryTest$B";
173                         %5 : TryTest$A = var.load %2;
174                         %6 : TryTest$B = field.load %5 @"TryTest$A::b()TryTest$B";
175                         %7 : TryTest$C = field.load %6 @"TryTest$B::c()TryTest$C";
176                         %8 : Var<TryTest$C> = var %7 @"c";
177                         %9 : Tuple<Var<TryTest$A>, TryTest$B, Var<TryTest$C>> = tuple %2 %4 %8;
178                         yield %9;
179                     }
180                     (%10 : Var<TryTest$A>, %11 : Var<TryTest$C>)void -> {
181                         %12 : TryTest$A = var.load %10;
182                         %13 : Var<TryTest$A> = var %12 @"_a";
183                         %14 : TryTest$C = var.load %11;
184                         %15 : Var<TryTest$C> = var %14 @"_c";
185                         yield;
186                     }
187                     ^catch(%16 : java.lang.Throwable)void -> {
188                         %17 : Var<java.lang.Throwable> = var %16 @"t";
189                         %18 : java.lang.Throwable = var.load %17;
190                         invoke %18 @"java.lang.Throwable::printStackTrace()void";
191                         yield;
192                     }
193                     ^finally()void -> {
194                         %19 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream";
195                         %20 : java.lang.String = constant @"F";
196                         invoke %19 %20 @"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 : TryTest)void -> {
216                 %1 : int = constant @"0";
217                 %2 : Var<int> = var %1 @"i";
218                 java.try
219                     ()void -> {
220                         %3 : int = constant @"1";
221                         var.store %2 %3;
222                         yield;
223                     }
224                     ^catch(%4 : java.lang.NullPointerException)void -> {
225                         %5 : Var<java.lang.NullPointerException> = var %4 @"e";
226                         %6 : int = constant @"2";
227                         var.store %2 %6;
228                         yield;
229                     }
230                     ^catch(%7 : java.lang.OutOfMemoryError)void -> {
231                         %8 : Var<java.lang.OutOfMemoryError> = var %7 @"e";
232                         %9 : 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 : TryTest)void -> {
253                 %1 : int = constant @"0";
254                 %2 : Var<int> = var %1 @"i";
255                 java.try
256                     ()void -> {
257                         return;
258                     }
259                     ^catch(%3 : java.lang.Exception)void -> {
260                         %4 : Var<java.lang.Exception> = var %3 @"e";
261                         %5 : java.lang.Exception = var.load %4;
262                         throw %5;
263                     }
264                     ^finally()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 }