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 }--- EOF ---