Skip to content

Commit 7d1abc1

Browse files
committed
Correcting LineNumberTable for rule switches.
1 parent 25f1b76 commit 7d1abc1

File tree

5 files changed

+114
-8
lines changed

5 files changed

+114
-8
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3636,7 +3636,7 @@ private void handleSwitch(JCTree tree, JCExpression selector, List<JCCase> cases
36363636

36373637
for (JCCase c : convertedCases) {
36383638
if (c.caseKind == JCCase.RULE && c.completesNormally) {
3639-
JCBreak b = make_at(c.pos()).Break(null);
3639+
JCBreak b = make.at(TreeInfo.endPos(c.stats.last())).Break(null);
36403640
b.target = tree;
36413641
c.stats = c.stats.append(b);
36423642
}

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ private void handleSwitch(JCTree tree,
420420
currentValue = temp;
421421
JCExpression test = (JCExpression) this.<JCTree>translate(p);
422422
c.stats = translate(c.stats);
423-
JCContinue continueSwitch = make.Continue(null);
423+
JCContinue continueSwitch = make.at(clearedPatterns.head.pos()).Continue(null);
424424
continueSwitch.target = tree;
425425
c.stats = c.stats.prepend(make.If(makeUnary(Tag.NOT, test).setType(syms.booleanType),
426426
make.Block(0, List.of(make.Exec(make.Assign(make.Ident(index),
@@ -468,7 +468,7 @@ private void handleSwitch(JCTree tree,
468468
previousCompletesNormally = c.completesNormally;
469469
} else {
470470
previousCompletesNormally = false;
471-
JCBreak brk = make.Break(null);
471+
JCBreak brk = make.at(TreeInfo.endPos(c.stats.last())).Break(null);
472472
brk.target = tree;
473473
c.stats = c.stats.append(brk);
474474
}

test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protected void test(List<TestCase> testCases) throws Exception {
6565
try {
6666
writeToFileIfEnabled(Paths.get(testCase.getName() + ".java"), testCase.src);
6767
Set<Integer> coveredLines = new HashSet<>();
68-
for (JavaFileObject file : compile(testCase.src).getClasses().values()) {
68+
for (JavaFileObject file : compile(testCase.extraCompilerOptions, testCase.src).getClasses().values()) {
6969
ClassFile classFile = ClassFile.read(file.openInputStream());
7070
for (Method m : classFile.methods) {
7171
Code_attribute code_attribute = (Code_attribute) m.attributes.get(Code);
@@ -84,10 +84,17 @@ protected void test(List<TestCase> testCases) throws Exception {
8484
.collect(toList()));
8585
}
8686
}
87-
assertTrue(coveredLines.containsAll(testCase.expectedLines),
88-
format("All significant lines are not covered.%n" +
89-
"Covered: %s%n" +
90-
"Expected: %s%n", coveredLines, testCase.expectedLines));
87+
if (testCase.exactLines) {
88+
assertTrue(coveredLines.equals(testCase.expectedLines),
89+
format("Incorrect covered lines.%n" +
90+
"Covered: %s%n" +
91+
"Expected: %s%n", coveredLines, testCase.expectedLines));
92+
} else {
93+
assertTrue(coveredLines.containsAll(testCase.expectedLines),
94+
format("All significant lines are not covered.%n" +
95+
"Covered: %s%n" +
96+
"Expected: %s%n", coveredLines, testCase.expectedLines));
97+
}
9198
} catch (AssertionFailedException | CompilationException ex) {
9299
System.err.printf("# %-20s#%n", testCase.getName());
93100
int l = 0;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2021, 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 8262891
27+
* @summary Verify correct LineNumberTable for rule switches.
28+
* @library /tools/lib /tools/javac/lib ../lib
29+
* @modules jdk.compiler/com.sun.tools.javac.api
30+
* jdk.compiler/com.sun.tools.javac.main
31+
* jdk.compiler/com.sun.tools.javac.util
32+
* jdk.jdeps/com.sun.tools.classfile
33+
* @build toolbox.ToolBox InMemoryFileManager TestBase
34+
* @build LineNumberTestBase TestCase
35+
* @run main RuleSwitchBreaks
36+
*/
37+
38+
import java.util.List;
39+
40+
public class RuleSwitchBreaks extends LineNumberTestBase {
41+
public static void main(String[] args) throws Exception {
42+
new RuleSwitchBreaks().test();
43+
}
44+
45+
public void test() throws Exception {
46+
test(List.of(TEST_CASE));
47+
}
48+
49+
private static final TestCase[] TEST_CASE = new TestCase[] {
50+
new TestCase("""
51+
public class Test { // 1
52+
private void test(int i) { // 2
53+
switch (i) { // 3
54+
case 0 -> // 4
55+
System.out.println("a"); // 5
56+
case 1 -> // 6
57+
System.out.println("a"); // 7
58+
default -> // 8
59+
System.out.println("default"); // 9
60+
} //10
61+
} //11
62+
} //12
63+
""",
64+
List.of(1, 3, 5, 7, 9, 11),
65+
true,
66+
List.of(),
67+
"Test"),
68+
new TestCase("""
69+
public class TestGuards { // 1
70+
private void test(Object o) { // 2
71+
switch (o) { // 3
72+
case String s && s.isEmpty() -> // 4
73+
System.out.println("a"); // 5
74+
case String s -> // 6
75+
System.out.println("a"); // 7
76+
default -> // 8
77+
System.out.println("default"); // 9
78+
} //10
79+
} //11
80+
} //12
81+
""",
82+
List.of(1, 3, 4, 5, 6, 7, 9, 11),
83+
true,
84+
List.of("--enable-preview", "-source", System.getProperty("java.specification.version")),
85+
"TestGuards")
86+
};
87+
88+
}

test/langtools/tools/javac/classfiles/attributes/LineNumberTable/TestCase.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import java.util.Collection;
2525
import java.util.HashSet;
26+
import java.util.List;
2627
import java.util.Set;
2728

2829
/**
@@ -32,6 +33,8 @@
3233
public class TestCase {
3334
public final String src;
3435
public final Set<Integer> expectedLines;
36+
public final boolean exactLines;
37+
public final List<String> extraCompilerOptions;
3538

3639

3740
private final String name;
@@ -41,8 +44,16 @@ public String getName() {
4144
}
4245

4346
public TestCase(String src, Collection<Integer> expectedLines, String name) {
47+
this(src, expectedLines, false, List.of(), name);
48+
}
49+
50+
public TestCase(String src, Collection<Integer> expectedLines,
51+
boolean exactLines, List<String> extraCompilerOptions,
52+
String name) {
4453
this.src = src;
4554
this.expectedLines = new HashSet<>(expectedLines);
55+
this.exactLines = exactLines;
56+
this.extraCompilerOptions = extraCompilerOptions;
4657
this.name = name;
4758
}
4859
}

0 commit comments

Comments
 (0)