8037937: javac: AssertionError during LVT generation, wrong variable ranges
Reviewed-by: mcimadamore
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed May 28 21:47:30 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu May 29 15:28:01 2014 +0100
@@ -1925,6 +1925,13 @@
return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
}
+ void removeLastRange() {
+ Range lastRange = lastRange();
+ if (lastRange != null) {
+ aliveRanges.remove(lastRange);
+ }
+ }
+
@Override
public String toString() {
if (aliveRanges == null) {
@@ -1955,9 +1962,7 @@
}
}
} else {
- if (!aliveRanges.isEmpty()) {
- aliveRanges.remove(aliveRanges.size() - 1);
- }
+ removeLastRange();
}
}
@@ -1965,16 +1970,14 @@
if (aliveRanges.isEmpty()) {
return false;
}
- Range range = lastRange();
- return range.length == Character.MAX_VALUE;
+ return lastRange().length == Character.MAX_VALUE;
}
public boolean isLastRangeInitialized() {
if (aliveRanges.isEmpty()) {
return false;
}
- Range range = lastRange();
- return range.start_pc != Character.MAX_VALUE;
+ return lastRange().start_pc != Character.MAX_VALUE;
}
public Range getWidestRange() {
@@ -2095,7 +2098,7 @@
v.closeRange(length);
putVar(v);
} else {
- v.lastRange().start_pc = Character.MAX_VALUE;
+ v.removeLastRange();
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed May 28 21:47:30 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu May 29 15:28:01 2014 +0100
@@ -1800,8 +1800,7 @@
genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
thenExit = code.branch(goto_);
if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) {
- code.closeAliveRanges(tree.thenpart,
- thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp);
+ code.closeAliveRanges(tree.thenpart, code.cp);
}
}
if (elseChain != null) {
--- a/langtools/test/tools/javac/flow/LVTHarness.java Wed May 28 21:47:30 2014 +0100
+++ b/langtools/test/tools/javac/flow/LVTHarness.java Thu May 29 15:28:01 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
/*
* @test
- * @bug 7047734 8027660
- * @summary The LVT is not generated correctly during some try/catch scenarios;
+ * @bug 7047734 8027660 8037937
+ * @summary The LVT is not generated correctly during some try/catch scenarios
* javac crash while creating LVT entry for a local variable defined in
* an inner block
* @library /tools/javac/lib
@@ -120,7 +120,7 @@
for (Map.Entry<ElementKey, AliveRanges> entry : aliveRangeMap.entrySet()) {
if (!seenAliveRanges.contains(entry.getKey())) {
error("Redundant @AliveRanges annotation on method " +
- entry.getKey().elem);
+ entry.getKey().elem + " with key " + entry.getKey());
}
}
}
@@ -134,7 +134,7 @@
for (Method method : classFile.methods) {
for (ElementKey elementKey: aliveRangeMap.keySet()) {
String methodDesc = method.getName(constantPool) +
- method.descriptor.getParameterTypes(constantPool);
+ method.descriptor.getParameterTypes(constantPool).replace(" ", "");
if (methodDesc.equals(elementKey.elem.toString())) {
checkMethod(constantPool, method, aliveRangeMap.get(elementKey));
seenAliveRanges.add(elementKey);
--- a/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java Wed May 28 21:47:30 2014 +0100
+++ b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java Thu May 29 15:28:01 2014 +0100
@@ -33,7 +33,7 @@
@AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
@AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9)
- void m2(String[] args) {
+ void m2() {
Object o;
int i = 5;
if (i != 5) {
@@ -45,4 +45,19 @@
}
o = "finish";
}
+
+ @AliveRange(varName="o", bytecodeStart=11, bytecodeLength=3)
+ @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=2)
+ Object m3(boolean cond1, boolean cond2) {
+ Object o;
+ if (cond1) {
+ if (cond2) {
+ o = "then";
+ } else {
+ o = "else";
+ return null;
+ }
+ }
+ return null;
+ }
}