1 /* 2 * Copyright (c) 2020, 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 8243047 27 * @summary javac should not crash while processing exits in class initializers in Flow 28 * @library /tools/lib /tools/javac/lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.file 31 * jdk.compiler/com.sun.tools.javac.main 32 * jdk.compiler/com.sun.tools.javac.util 33 * @build toolbox.ToolBox toolbox.JavacTask 34 * @build combo.ComboTestHelper 35 * @compile ClassBlockExits.java 36 * @run main ClassBlockExits 37 */ 38 39 import combo.ComboInstance; 40 import combo.ComboParameter; 41 import combo.ComboTask; 42 import combo.ComboTestHelper; 43 import java.io.StringWriter; 44 import toolbox.ToolBox; 45 46 public class ClassBlockExits extends ComboInstance<ClassBlockExits> { 47 protected ToolBox tb; 48 49 ClassBlockExits() { 50 super(); 51 tb = new ToolBox(); 52 } 53 54 public static void main(String... args) throws Exception { 55 new ComboTestHelper<ClassBlockExits>() 56 .withDimension("BLOCK", (x, block) -> x.block = block, Block.values()) 57 .withDimension("EXIT", (x, exit) -> x.exit = exit, Exit.values()) 58 .run(ClassBlockExits::new); 59 } 60 61 private Block block; 62 private Exit exit; 63 64 private static final String MAIN_TEMPLATE = 65 """ 66 public class Test { 67 #{BLOCK} 68 void t() {} 69 } 70 """; 71 72 @Override 73 protected void doWork() throws Throwable { 74 StringWriter out = new StringWriter(); 75 76 ComboTask task = newCompilationTask() 77 .withSourceFromTemplate(MAIN_TEMPLATE, pname -> switch (pname) { 78 case "BLOCK" -> block; 79 case "BODY" -> exit; 80 default -> throw new UnsupportedOperationException(pname); 81 }) 82 .withOption("-XDshould-stop.at=FLOW") 83 .withOption("-XDdev") 84 .withWriter(out); 85 86 task.analyze(result -> { 87 if (out.toString().length() > 0) { 88 throw new AssertionError("No output expected, but got" + out + "\n\n" + result.compilationInfo()); 89 } 90 }); 91 } 92 93 public enum Block implements ComboParameter { 94 STATIC(""" 95 static { 96 #{BODY} 97 } 98 """), 99 INSTANCE(""" 100 { 101 #{BODY} 102 } 103 """), 104 STATIC_INITIALIZER(""" 105 private static int i = switch (0) { default: #{BODY} case 0: yield 0; }; 106 """), 107 INITIALIZER(""" 108 private int i = switch (0) { default: #{BODY} case 0: yield 0; }; 109 """); 110 private final String block; 111 112 private Block(String block) { 113 this.block = block; 114 } 115 116 @Override 117 public String expand(String optParameter) { 118 return block; 119 } 120 } 121 122 public enum Exit implements ComboParameter { 123 RETURN("return;"), 124 RETURN_VALUE("return null;"), 125 BREAK("break;"), 126 BREAK_LABEL("break LABEL;"), 127 CONTINUE("continue;"), 128 CONTINUE_LABEL("continue LABEL;"), 129 YIELD("yield 0;"); 130 private final String code; 131 132 private Exit(String code) { 133 this.code = code; 134 } 135 136 @Override 137 public String expand(String optParameter) { 138 return code; 139 } 140 } 141 }