Skip to content

Commit fe89dd3

Browse files
committed
8271254: javac generates unreachable code when using empty semicolon statement
Reviewed-by: vromero
1 parent 8974b95 commit fe89dd3

File tree

2 files changed

+101
-9
lines changed

2 files changed

+101
-9
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,8 @@ void afterBody() {
15101510
//where
15111511
/** Generate code for a try or synchronized statement
15121512
* @param body The body of the try or synchronized statement.
1513-
* @param catchers The lis of catch clauses.
1514-
* @param env the environment current for the body.
1513+
* @param catchers The list of catch clauses.
1514+
* @param env The current environment of the body.
15151515
*/
15161516
void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) {
15171517
int limit = code.nextreg;
@@ -1523,7 +1523,13 @@ void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) {
15231523
code.statBegin(TreeInfo.endPos(body));
15241524
genFinalizer(env);
15251525
code.statBegin(TreeInfo.endPos(env.tree));
1526-
Chain exitChain = code.branch(goto_);
1526+
Chain exitChain;
1527+
boolean actualTry = env.tree.hasTag(TRY);
1528+
if (startpc == endpc && actualTry) {
1529+
exitChain = code.branch(dontgoto);
1530+
} else {
1531+
exitChain = code.branch(goto_);
1532+
}
15271533
endFinalizerGap(env);
15281534
env.info.finalize.afterBody();
15291535
boolean hasFinalizer =
@@ -1541,7 +1547,7 @@ void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) {
15411547
}
15421548
endFinalizerGap(env);
15431549
}
1544-
if (hasFinalizer) {
1550+
if (hasFinalizer && (startpc != endpc || !actualTry)) {
15451551
// Create a new register segment to avoid allocating
15461552
// the same variables in finalizers and other statements.
15471553
code.newRegSegment();

test/langtools/tools/javac/T8022186/DeadCodeGeneratedForEmptyTryTest.java

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8022186
26+
* @bug 8022186 8271254
2727
* @summary javac generates dead code if a try with an empty body has a finalizer
2828
* @modules jdk.jdeps/com.sun.tools.classfile
2929
* jdk.compiler/com.sun.tools.javac.util
@@ -53,15 +53,18 @@ public static void main(String[] args) throws Exception {
5353
}
5454

5555
void run() throws Exception {
56-
checkClassFile(Paths.get(System.getProperty("test.classes"),
57-
this.getClass().getName() + "$Test.class"));
56+
for (int i = 1; i <= 8; i++) {
57+
checkClassFile(Paths.get(System.getProperty("test.classes"),
58+
this.getClass().getName() + "$Test" + i + ".class"));
59+
}
5860
}
5961

6062
int utf8Index;
6163
int numberOfRefToStr = 0;
6264
ConstantPool constantPool;
6365

6466
void checkClassFile(final Path path) throws Exception {
67+
numberOfRefToStr = 0;
6568
ClassFile classFile = ClassFile.read(
6669
new BufferedInputStream(Files.newInputStream(path)));
6770
constantPool = classFile.constant_pool;
@@ -155,9 +158,92 @@ public Void visitUnknown(Instruction instr, Void p) {
155158

156159
}
157160

158-
public class Test {
161+
public class Test1 {
162+
void methodToLookFor() {
163+
try {
164+
// empty intentionally
165+
} finally {
166+
System.out.println("STR_TO_LOOK_FOR");
167+
}
168+
}
169+
}
170+
171+
public class Test2 {
172+
void methodToLookFor() {
173+
try {
174+
// empty intentionally
175+
} catch (Exception e) {
176+
System.out.println("EXCEPTION");
177+
} finally {
178+
System.out.println("STR_TO_LOOK_FOR");
179+
}
180+
}
181+
}
182+
183+
public class Test3 {
184+
void methodToLookFor() {
185+
try {
186+
; // skip statement intentionally
187+
} finally {
188+
System.out.println("STR_TO_LOOK_FOR");
189+
}
190+
}
191+
}
192+
193+
public class Test4 {
194+
void methodToLookFor() {
195+
try {
196+
; // skip statement intentionally
197+
} catch (Exception e) {
198+
System.out.println("EXCEPTION");
199+
} finally {
200+
System.out.println("STR_TO_LOOK_FOR");
201+
}
202+
}
203+
}
204+
205+
public class Test5 {
206+
void methodToLookFor() {
207+
try {
208+
// empty try statement
209+
try { } finally { }
210+
} finally {
211+
System.out.println("STR_TO_LOOK_FOR");
212+
}
213+
}
214+
}
215+
216+
public class Test6 {
217+
void methodToLookFor() {
218+
try {
219+
// empty try statement
220+
try { } catch (Exception e) { } finally { }
221+
} catch (Exception e) {
222+
System.out.println("EXCEPTION");
223+
} finally {
224+
System.out.println("STR_TO_LOOK_FOR");
225+
}
226+
}
227+
}
228+
229+
public class Test7 {
230+
void methodToLookFor() {
231+
try {
232+
// empty try statement with skip statement
233+
try { ; } finally { }
234+
} finally {
235+
System.out.println("STR_TO_LOOK_FOR");
236+
}
237+
}
238+
}
239+
240+
public class Test8 {
159241
void methodToLookFor() {
160242
try {
243+
// empty try statement with skip statement
244+
try { ; } catch (Exception e) { } finally { }
245+
} catch (Exception e) {
246+
System.out.println("EXCEPTION");
161247
} finally {
162248
System.out.println("STR_TO_LOOK_FOR");
163249
}

0 commit comments

Comments
 (0)