1 /*
   2  * Copyright (c) 2018, 2019, 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 8214031 8214114
  27  * @summary Verify switch expressions embedded in various statements work properly.
  28  * @compile ExpressionSwitchEmbedding.java
  29  * @run main ExpressionSwitchEmbedding
  30  */
  31 
  32 public class ExpressionSwitchEmbedding {
  33     public static void main(String... args) {
  34         new ExpressionSwitchEmbedding().run();
  35     }
  36 
  37     private void run() {
  38         {
  39             int i = 6;
  40             int o = 0;
  41             while (switch (i) {
  42                 case 1: i = 0; yield true;
  43                 case 2: i = 1; yield true;
  44                 case 3, 4: i--;
  45                     if (i == 2 || i == 4) {
  46                         yield switch (i) {
  47                             case 2 -> true;
  48                             case 4 -> false;
  49                             default -> throw new IllegalStateException();
  50                         };
  51                     } else {
  52                         yield true;
  53                     }
  54                 default: i--; yield switch (i) {
  55                     case -1 -> false;
  56                     case 3 -> true;
  57                     default -> true;
  58                 };
  59             }) {
  60                 o++;
  61             }
  62             if (o != 6 && i >= 0) {
  63                 throw new IllegalStateException();
  64             }
  65         }
  66         {
  67             int i = 6;
  68             int o = 0;
  69             while (switch (i) {
  70                 case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
  71                 case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
  72                 case 3, 4:
  73                     try {
  74                         new ExpressionSwitchEmbedding().throwException();
  75                     } catch (Throwable t) {
  76                         i--;
  77                         if (i == 2 || i == 4) {
  78                             try {
  79                                 yield switch (i) {
  80                                     case 2 -> throw new ResultException(true);
  81                                     case 4 -> false;
  82                                     default -> throw new IllegalStateException();
  83                                 };
  84                             } catch (ResultException ex) {
  85                                 yield ex.result;
  86                             }
  87                         } else {
  88                             yield true;
  89                         }
  90                     }
  91                 default:
  92                     try {
  93                         new ExpressionSwitchEmbedding().throwException();
  94                     } catch (Throwable t) {
  95                         i--;
  96                         yield switch (i) {
  97                             case -1 -> false;
  98                             case 3 -> true;
  99                             default -> true;
 100                         };
 101                     }
 102                     throw new AssertionError();
 103             }) {
 104                 o++;
 105             }
 106             if (o != 6 && i >= 0) {
 107                 throw new IllegalStateException();
 108             }
 109         }
 110         {
 111             int i = 6;
 112             int o = 0;
 113             if (switch (i) {
 114                 case 1: i = 0; yield true;
 115                 case 2: i = 1; yield true;
 116                 case 3, 4: i--;
 117                     if (i == 2 || i == 4) {
 118                         yield (switch (i) {
 119                             case 2 -> 3;
 120                             case 4 -> 5;
 121                             default -> throw new IllegalStateException();
 122                         }) == i + 1;
 123                     } else {
 124                         yield true;
 125                     }
 126                 default: i--; yield switch (i) {
 127                     case -1 -> false;
 128                     case 3 -> true;
 129                     default -> true;
 130                 };
 131             }) {
 132                 o++;
 133             }
 134             if (o != 1 && i != 5) {
 135                 throw new IllegalStateException();
 136             }
 137         }
 138         {
 139             int i = 6;
 140             int o = 0;
 141             if (switch (i) {
 142                 case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
 143                 case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
 144                 case 3, 4:
 145                     try {
 146                         new ExpressionSwitchEmbedding().throwException();
 147                     } catch (Throwable t) {
 148                         i--;
 149                         if (i == 2 || i == 4) {
 150                             try {
 151                                 yield switch (i) {
 152                                     case 2 -> throw new ResultException(true);
 153                                     case 4 -> false;
 154                                     default -> throw new IllegalStateException();
 155                                 };
 156                             } catch (ResultException ex) {
 157                                 yield ex.result;
 158                             }
 159                         } else {
 160                             yield true;
 161                         }
 162                     }
 163                 default:
 164                     try {
 165                         new ExpressionSwitchEmbedding().throwException();
 166                     } catch (Throwable t) {
 167                         i--;
 168                         yield switch (i) {
 169                             case -1 -> false;
 170                             case 3 -> true;
 171                             default -> true;
 172                         };
 173                     }
 174                     throw new AssertionError();
 175             }) {
 176                 o++;
 177             }
 178             if (o != 1 && i != 5) {
 179                 throw new IllegalStateException();
 180             }
 181         }
 182         {
 183             int o = 0;
 184             for (int i = 6; (switch (i) {
 185                 case 1: i = 0; yield true;
 186                 case 2: i = 1; yield true;
 187                 case 3, 4: i--;
 188                     if (i == 2 || i == 4) {
 189                         yield switch (i) {
 190                             case 2 -> true;
 191                             case 4 -> false;
 192                             default -> throw new IllegalStateException();
 193                         };
 194                     } else {
 195                         yield true;
 196                     }
 197                 default: i--; yield switch (i) {
 198                     case -1 -> false;
 199                     case 3 -> true;
 200                     default -> true;
 201                 };
 202             }); ) {
 203                 o++;
 204             }
 205             if (o != 6) {
 206                 throw new IllegalStateException();
 207             }
 208         }
 209         {
 210             int o = 0;
 211             for (int i = 6; (switch (i) {
 212                 case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
 213                 case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
 214                 case 3, 4:
 215                     try {
 216                         new ExpressionSwitchEmbedding().throwException();
 217                     } catch (Throwable t) {
 218                         i--;
 219                         if (i == 2 || i == 4) {
 220                             try {
 221                                 yield switch (i) {
 222                                     case 2 -> throw new ResultException(true);
 223                                     case 4 -> false;
 224                                     default -> throw new IllegalStateException();
 225                                 };
 226                             } catch (ResultException ex) {
 227                                 yield ex.result;
 228                             }
 229                         } else {
 230                             yield true;
 231                         }
 232                     }
 233                 default:
 234                     try {
 235                         new ExpressionSwitchEmbedding().throwException();
 236                     } catch (Throwable t) {
 237                         i--;
 238                         yield switch (i) {
 239                             case -1 -> false;
 240                             case 3 -> true;
 241                             default -> true;
 242                         };
 243                     }
 244                     throw new AssertionError();
 245             }); ) {
 246                 o++;
 247             }
 248             if (o != 6) {
 249                 throw new IllegalStateException();
 250             }
 251         }
 252         {
 253             int i = 6;
 254             int o = 0;
 255             do {
 256                 o++;
 257             } while (switch (i) {
 258                 case 1: i = 0; yield true;
 259                 case 2: i = 1; yield true;
 260                 case 3, 4: i--;
 261                     if (i == 2 || i == 4) {
 262                         yield switch (i) {
 263                             case 2 -> true;
 264                             case 4 -> false;
 265                             default -> throw new IllegalStateException();
 266                         };
 267                     } else {
 268                         yield true;
 269                     }
 270                 default: i--; yield switch (i) {
 271                     case -1 -> false;
 272                     case 3 -> true;
 273                     default -> true;
 274                 };
 275             });
 276             if (o != 6 && i >= 0) {
 277                 throw new IllegalStateException();
 278             }
 279         }
 280         {
 281             int i = 6;
 282             int o = 0;
 283             do {
 284                 o++;
 285             } while (switch (i) {
 286                 case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
 287                 case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
 288                 case 3, 4:
 289                     try {
 290                         new ExpressionSwitchEmbedding().throwException();
 291                     } catch (Throwable t) {
 292                         i--;
 293                         if (i == 2 || i == 4) {
 294                             try {
 295                                 yield switch (i) {
 296                                     case 2 -> throw new ResultException(true);
 297                                     case 4 -> false;
 298                                     default -> throw new IllegalStateException();
 299                                 };
 300                             } catch (ResultException ex) {
 301                                 yield ex.result;
 302                             }
 303                         } else {
 304                             yield true;
 305                         }
 306                     }
 307                 default:
 308                     try {
 309                         new ExpressionSwitchEmbedding().throwException();
 310                     } catch (Throwable t) {
 311                         i--;
 312                         yield switch (i) {
 313                             case -1 -> false;
 314                             case 3 -> true;
 315                             default -> true;
 316                         };
 317                     }
 318                     throw new AssertionError();
 319             });
 320             if (o != 6 && i >= 0) {
 321                 throw new IllegalStateException();
 322             }
 323         }
 324     }
 325 
 326     private void throwException() {
 327         throw new RuntimeException();
 328     }
 329 
 330     private static final class ResultException extends RuntimeException {
 331         public final boolean result;
 332         public ResultException(boolean result) {
 333             this.result = result;
 334         }
 335     }
 336 }