8027660: javac crash while creating LVT entry for a local variable defined in an inner block
Reviewed-by: jjg
Contributed-by: vicente.romero@oracle.com, jan.lahoda@oracle.com
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed Oct 30 14:12:16 2013 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Fri Nov 01 19:08:56 2013 +0000
@@ -1790,8 +1790,9 @@
void markInitialized(UninitializedType old) {
Type newtype = old.initializedType();
- for (int i=0; i<stacksize; i++)
+ for (int i=0; i<stacksize; i++) {
if (stack[i] == old) stack[i] = newtype;
+ }
for (int i=0; i<lvar.length; i++) {
LocalVar lv = lvar[i];
if (lv != null && lv.sym.type == old) {
@@ -2112,7 +2113,6 @@
private void endScope(int adr) {
LocalVar v = lvar[adr];
if (v != null) {
- lvar[adr] = null;
if (v.isLastRangeInitialized()) {
char length = (char)(curCP() - v.lastRange().start_pc);
if (length < Character.MAX_VALUE) {
@@ -2121,6 +2121,12 @@
fillLocalVarPosition(v);
}
}
+ /** the call to curCP() can implicitly adjust the current cp, if so
+ * the alive range of local variables may be modified. Thus we need
+ * all of them. For this reason assigning null to the given address
+ * should be the last action to do.
+ */
+ lvar[adr] = null;
}
state.defined.excl(adr);
}
--- a/langtools/test/tools/javac/flow/LVTHarness.java Wed Oct 30 14:12:16 2013 -0400
+++ b/langtools/test/tools/javac/flow/LVTHarness.java Fri Nov 01 19:08:56 2013 +0000
@@ -23,8 +23,10 @@
/*
* @test
- * @bug 7047734
- * @summary The LVT is not generated correctly during some try/catch scenarios
+ * @bug 7047734 8027660
+ * @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
* @build JavacTestingAbstractProcessor LVTHarness
* @run main LVTHarness
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseLocalInInnerBlock.java Fri Nov 01 19:08:56 2013 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class TestCaseLocalInInnerBlock {
+
+ @AliveRange(varName="fm", bytecodeStart=23, bytecodeLength=10)
+ @AliveRange(varName="newWidth", bytecodeStart=2, bytecodeLength=33)
+ @AliveRange(varName="tc", bytecodeStart=5, bytecodeLength=30)
+ int m() {
+ int newWidth = 0;
+ String tc = "b";
+ if (tc != null) {
+ String fm;
+ if (tc.trim() != null) {
+ } else if ((fm = "b") != null) {
+ newWidth += fm.length();
+ }
+ }
+ return newWidth;
+ }
+}