1 /*
2  * Copyright (c) 2018, 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 /**
25  * @test
26  * @bug 8214114
27  * @summary Verify try-catch inside a switch expression works properly.
28  * @compile --enable-preview -source 12 TryCatch.java
29  * @run main/othervm --enable-preview TryCatch
30  */
31 public class TryCatch {
main(String[] args)32     public static void main(String[] args) {
33         {
34             int val = 3;
35             for (int p : new int[] {0, 1, 2}) {
36                 int res = 1 + new TryCatch().id(switch(p) {
37                     case 0 -> switch (p + 1) {
38                         case 1:
39                             try {
40                                 new TryCatch().throwException();
41                                 break -1;
42                             } catch(Throwable ex) {
43                                 break val;
44                             }
45                         default: break -1;
46                     };
47                     case 1 -> {
48                         try {
49                             break new TryCatch().id(switch (p + 1) {
50                                 case 2:
51                                     try {
52                                         new TryCatch().throwException();
53                                         break -1;
54                                     } catch(Throwable ex) {
55                                         throw ex;
56                                     }
57                                 default: break -1;
58                             });
59                         } catch(Throwable ex) {
60                             break val;
61                         }
62                     }
63                     default -> {
64                         try {
65                             new TryCatch().throwException();
66                             break -1;
67                         } catch(Throwable ex) {
68                             break val;
69                         }
70                     }
71                 } - 1);
72                 if (res != 3) {
73                     throw new AssertionError("Unexpected result: " + res);
74                 }
75             }
76         }
77         {
78             int val = 3;
79             for (int p : new int[] {0, 1, 2}) {
80                 int x;
81                 int res = new TryCatch().id(val == 3 && switch(p) {
82                     case 0 -> switch (p + 1) {
83                         case 1:
84                             try {
85                                 new TryCatch().throwException();
86                                 break false;
87                             } catch(Throwable ex) {
88                                 break true;
89                             }
90                         default: break false;
91                     };
92                     case 1 -> {
93                         try {
94                             break new TryCatch().id(switch (p + 1) {
95                                 case 2:
96                                     try {
97                                         new TryCatch().throwException();
98                                         break false;
99                                     } catch(Throwable ex) {
100                                         throw ex;
101                                     }
102                                 default: break false;
103                             });
104                         } catch(Throwable ex) {
105                             break true;
106                         }
107                     }
108                     default -> {
109                         try {
110                             new TryCatch().throwException();
111                             break false;
112                         } catch(Throwable ex) {
113                             break true;
114                         }
115                     }
116                 } && (x = 1) == 1 && x == 1 ? val : -1);
117                 if (res != 3) {
118                     throw new AssertionError("Unexpected result: " + res);
119                 }
120             }
121         }
122         {
123             int val = 3;
124             for (E e : new E[] {E.A, E.B, E.C}) {
125                 int res = 1 + new TryCatch().id(switch(e) {
126                     case A -> switch (e.next()) {
127                         case B:
128                             try {
129                                 new TryCatch().throwException();
130                                 break -1;
131                             } catch(Throwable ex) {
132                                 break val;
133                             }
134                         default: break -1;
135                     };
136                     case B -> {
137                         try {
138                             break new TryCatch().id(switch (e.next()) {
139                                 case C:
140                                     try {
141                                         new TryCatch().throwException();
142                                         break -1;
143                                     } catch(Throwable ex) {
144                                         throw ex;
145                                     }
146                                 default: break -1;
147                             });
148                         } catch(Throwable ex) {
149                             break val;
150                         }
151                     }
152                     default -> {
153                         try {
154                             new TryCatch().throwException();
155                             break -1;
156                         } catch(Throwable ex) {
157                             break val;
158                         }
159                     }
160                 } - 1);
161                 if (res != 3) {
162                     throw new AssertionError("Unexpected result: " + res);
163                 }
164             }
165         }
166         {
167             int val = 3;
168             for (E e : new E[] {E.A, E.B, E.C}) {
169                 int x;
170                 int res = new TryCatch().id(val == 3 && switch(e) {
171                     case A -> switch (e.next()) {
172                         case B:
173                             try {
174                                 new TryCatch().throwException();
175                                 break false;
176                             } catch(Throwable ex) {
177                                 break true;
178                             }
179                         default: break false;
180                     };
181                     case B -> {
182                         try {
183                             break new TryCatch().id(switch (e.next()) {
184                                 case C:
185                                     try {
186                                         new TryCatch().throwException();
187                                         break false;
188                                     } catch(Throwable ex) {
189                                         throw ex;
190                                     }
191                                 default: break false;
192                             });
193                         } catch(Throwable ex) {
194                             break true;
195                         }
196                     }
197                     default -> {
198                         try {
199                             new TryCatch().throwException();
200                             break false;
201                         } catch(Throwable ex) {
202                             break true;
203                         }
204                     }
205                 } && (x = 1) == 1 && x == 1 ? val : -1);
206                 if (res != 3) {
207                     throw new AssertionError("Unexpected result: " + res);
208                 }
209             }
210         }
211         {
212             int val = 3;
213             for (String s : new String[] {"", "a", "b"}) {
214                 int res = 1 + new TryCatch().id(switch(s) {
215                     case "" -> switch (s + "c") {
216                         case "c":
217                             try {
218                                 new TryCatch().throwException();
219                                 break -1;
220                             } catch(Throwable ex) {
221                                 break val;
222                             }
223                         default: break -1;
224                     };
225                     case "a" -> {
226                         try {
227                             break new TryCatch().id(switch (s + "c") {
228                                 case "ac":
229                                     try {
230                                         new TryCatch().throwException();
231                                         break -1;
232                                     } catch(Throwable ex) {
233                                         throw ex;
234                                     }
235                                 default: break -1;
236                             });
237                         } catch(Throwable ex) {
238                             break val;
239                         }
240                     }
241                     default -> {
242                         try {
243                             new TryCatch().throwException();
244                             break -1;
245                         } catch(Throwable ex) {
246                             break val;
247                         }
248                     }
249                 } - 1);
250                 if (res != 3) {
251                     throw new AssertionError("Unexpected result: " + res);
252                 }
253             }
254         }
255         {
256             int val = 3;
257             for (String s : new String[] {"", "a", "b"}) {
258                 int x;
259                 int res = new TryCatch().id(val == 3 && switch(s) {
260                     case "" -> switch (s + "c") {
261                         case "c":
262                             try {
263                                 new TryCatch().throwException();
264                                 break false;
265                             } catch(Throwable ex) {
266                                 break true;
267                             }
268                         default: break false;
269                     };
270                     case "a" -> {
271                         try {
272                             break new TryCatch().id(switch (s + "c") {
273                                 case "ac":
274                                     try {
275                                         new TryCatch().throwException();
276                                         break false;
277                                     } catch(Throwable ex) {
278                                         throw ex;
279                                     }
280                                 default: break false;
281                             });
282                         } catch(Throwable ex) {
283                             break true;
284                         }
285                     }
286                     default -> {
287                         try {
288                             new TryCatch().throwException();
289                             break false;
290                         } catch(Throwable ex) {
291                             break true;
292                         }
293                     }
294                 } && (x = 1) == 1 && x == 1 ? val : -1);
295                 if (res != 3) {
296                     throw new AssertionError("Unexpected result: " + res);
297                 }
298             }
299         }
300 
301         {
302             int res = new FieldHolder().intTest;
303 
304             if (res != 3) {
305                 throw new AssertionError("Unexpected result: " + res);
306             }
307         }
308         {
309             int res = FieldHolder.intStaticTest;
310 
311             if (res != 3) {
312                 throw new AssertionError("Unexpected result: " + res);
313             }
314         }
315         {
316             boolean res = new FieldHolder().booleanTest;
317 
318             if (!res) {
319                 throw new AssertionError("Unexpected result: " + res);
320             }
321         }
322         {
323             boolean res = FieldHolder.booleanStaticTest;
324 
325             if (!res) {
326                 throw new AssertionError("Unexpected result: " + res);
327             }
328         }
329     }
330 
331     static class FieldHolder {
332         private final int intTest = switch (0) {
333             case -1: break -1;
334             default:
335                 try {
336                     break new TryCatch().id(switch (2) {
337                         case 2:
338                             try {
339                                 new TryCatch().throwException();
340                                 break -1;
341                             } catch(Throwable ex) {
342                                 throw ex;
343                             }
344                         default: break -1;
345                     });
346                 } catch(Throwable ex) {
347                     break 3;
348                 }
349         };
350         private static final int intStaticTest = switch (0) {
351             case -1: break -1;
352             default:
353                 try {
354                     break new TryCatch().id(switch (2) {
355                         case 2:
356                             try {
357                                 new TryCatch().throwException();
358                                 break -1;
359                             } catch(Throwable ex) {
360                                 throw ex;
361                             }
362                         default: break -1;
363                     });
364                 } catch(Throwable ex) {
365                     break 3;
366                 }
367         };
368         private final boolean booleanTest = switch (0) {
369             case -1: break false;
370             default:
371                 try {
372                     break new TryCatch().id(switch (2) {
373                         case 2:
374                             try {
375                                 new TryCatch().throwException();
376                                 break false;
377                             } catch(Throwable ex) {
378                                 throw ex;
379                             }
380                         default: break false;
381                     });
382                 } catch(Throwable ex) {
383                     break true;
384                 }
385         };
386         private static final boolean booleanStaticTest = switch (0) {
387             case -1: break false;
388             default:
389                 try {
390                     break new TryCatch().id(switch (2) {
391                         case 2:
392                             try {
393                                 new TryCatch().throwException();
394                                 break false;
395                             } catch(Throwable ex) {
396                                 throw ex;
397                             }
398                         default: break false;
399                     });
400                 } catch(Throwable ex) {
401                     break true;
402                 }
403         };
404     }
405 
id(int i)406     private int id(int i) {
407         return i;
408     }
409 
id(boolean b)410     private boolean id(boolean b) {
411         return b;
412     }
413 
throwException()414     private void throwException() {
415         throw new RuntimeException();
416     }
417     enum E {
418         A, B, C;
next()419         public E next() {
420             return values()[(ordinal() + 1) % values().length];
421         }
422     }
423 }
424