8027660: javac crash while creating LVT entry for a local variable defined in an inner block
authorvromero
Fri, 01 Nov 2013 19:08:56 +0000
changeset 21703 b12ce201d445
parent 21505 403632350961
child 21704 e215a6216604
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
langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
langtools/test/tools/javac/flow/LVTHarness.java
langtools/test/tools/javac/flow/tests/TestCaseLocalInInnerBlock.java
--- 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;
+    }
+}