8010659: Javac Crashes while building OpenJFX
authorvromero
Sat, 13 Apr 2013 12:25:44 +0100
changeset 16968 19f0da2d3143
parent 16967 79d444669f3f
child 16969 b58d8a70d921
8010659: Javac Crashes while building OpenJFX Reviewed-by: jjg Contributed-by: maurizio.cimadamore@oracle.com
langtools/src/share/classes/com/sun/tools/javac/comp/CompileStates.java
langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
langtools/test/tools/javac/T8010659/CompilerCrashWhenMixingBinariesAndSourcesTest.java
langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java
langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/CompileStates.java	Sat Apr 13 12:25:44 2013 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.tools.javac.comp;
+
+import java.util.HashMap;
+
+import com.sun.tools.javac.util.Context;
+
+/** Partial map to record which compiler phases have been executed
+ *  for each compilation unit. Used for ATTR and FLOW phases.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class CompileStates extends HashMap<Env<AttrContext>, CompileStates.CompileState> {
+    /** The context key for the compile states. */
+    protected static final Context.Key<CompileStates> compileStatesKey =
+        new Context.Key<CompileStates>();
+
+    /** Get the CompileStates instance for this context. */
+    public static CompileStates instance(Context context) {
+        CompileStates instance = context.get(compileStatesKey);
+        if (instance == null) {
+            instance = new CompileStates(context);
+        }
+        return instance;
+    }
+
+    /** Ordered list of compiler phases for each compilation unit. */
+    public enum CompileState {
+        INIT(0),
+        PARSE(1),
+        ENTER(2),
+        PROCESS(3),
+        ATTR(4),
+        FLOW(5),
+        TRANSTYPES(6),
+        UNLAMBDA(7),
+        LOWER(8),
+        GENERATE(9);
+
+        CompileState(int value) {
+            this.value = value;
+        }
+        public boolean isAfter(CompileState other) {
+            return value > other.value;
+        }
+        public static CompileState max(CompileState a, CompileState b) {
+            return a.value > b.value ? a : b;
+        }
+        private final int value;
+    };
+
+    private static final long serialVersionUID = 1812267524140424433L;
+
+    protected Context context;
+
+    public CompileStates(Context context) {
+        this.context = context;
+        context.put(compileStatesKey, this);
+    }
+
+    public boolean isDone(Env<AttrContext> env, CompileState cs) {
+        CompileState ecs = get(env);
+        return (ecs != null) && !cs.isAfter(ecs);
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Apr 12 12:05:04 2013 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Sat Apr 13 12:25:44 2013 +0100
@@ -40,6 +40,7 @@
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
 import static com.sun.tools.javac.code.TypeTag.VOID;
+import static com.sun.tools.javac.comp.CompileStates.CompileState;
 
 /** This pass translates Generic Java to conventional Java.
  *
@@ -77,8 +78,11 @@
      */
     private final boolean addBridges;
 
+    private final CompileStates compileStates;
+
     protected TransTypes(Context context) {
         context.put(transTypesKey, this);
+        compileStates = CompileStates.instance(context);
         names = Names.instance(context);
         log = Log.instance(context);
         syms = Symtab.instance(context);
@@ -904,16 +908,40 @@
 
     private Env<AttrContext> env;
 
+    private static final String statePreviousToFlowAssertMsg =
+            "The current compile state [%s] of class %s is previous to FLOW";
+
     void translateClass(ClassSymbol c) {
         Type st = types.supertype(c.type);
-
         // process superclass before derived
-        if (st.hasTag(CLASS))
+        if (st.hasTag(CLASS)) {
             translateClass((ClassSymbol)st.tsym);
+        }
 
         Env<AttrContext> myEnv = enter.typeEnvs.remove(c);
-        if (myEnv == null)
+        if (myEnv == null) {
             return;
+        }
+
+        /*  The two assertions below are set for early detection of any attempt
+         *  to translate a class that:
+         *
+         *  1) has no compile state being it the most outer class.
+         *     We accept this condition for inner classes.
+         *
+         *  2) has a compile state which is previous to Flow state.
+         */
+        boolean envHasCompState = compileStates.get(myEnv) != null;
+        if (!envHasCompState && c.outermostClass() == c) {
+            Assert.error("No info for outermost class: " + myEnv.enclClass.sym);
+        }
+
+        if (envHasCompState &&
+                CompileState.FLOW.isAfter(compileStates.get(myEnv))) {
+            Assert.error(String.format(statePreviousToFlowAssertMsg,
+                    compileStates.get(myEnv), myEnv.enclClass.sym));
+        }
+
         Env<AttrContext> oldEnv = env;
         try {
             env = myEnv;
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Apr 12 12:05:04 2013 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Sat Apr 13 12:25:44 2013 +0100
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.main;
 
+import com.sun.tools.javac.comp.CompileStates;
 import java.io.*;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -61,6 +62,7 @@
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.util.Log.WriterKind;
 
 import static com.sun.tools.javac.code.TypeTag.CLASS;
@@ -326,6 +328,8 @@
      **/
     protected boolean implicitSourceFilesRead;
 
+    protected CompileStates compileStates;
+
     /** Construct a new compiler using a shared context.
      */
     public JavaCompiler(Context context) {
@@ -348,6 +352,7 @@
 
         fileManager = context.get(JavaFileManager.class);
         parserFactory = ParserFactory.instance(context);
+        compileStates = CompileStates.instance(context);
 
         try {
             // catch completion problems with predefineds
@@ -521,42 +526,6 @@
      */
     public List<Closeable> closeables = List.nil();
 
-    /** Ordered list of compiler phases for each compilation unit. */
-    public enum CompileState {
-        INIT(0),
-        PARSE(1),
-        ENTER(2),
-        PROCESS(3),
-        ATTR(4),
-        FLOW(5),
-        TRANSTYPES(6),
-        UNLAMBDA(7),
-        LOWER(8),
-        GENERATE(9);
-
-        CompileState(int value) {
-            this.value = value;
-        }
-        boolean isAfter(CompileState other) {
-            return value > other.value;
-        }
-        public static CompileState max(CompileState a, CompileState b) {
-            return a.value > b.value ? a : b;
-        }
-        private final int value;
-    };
-    /** Partial map to record which compiler phases have been executed
-     * for each compilation unit. Used for ATTR and FLOW phases.
-     */
-    protected class CompileStates extends HashMap<Env<AttrContext>,CompileState> {
-        private static final long serialVersionUID = 1812267524140424433L;
-        boolean isDone(Env<AttrContext> env, CompileState cs) {
-            CompileState ecs = get(env);
-            return (ecs != null) && !cs.isAfter(ecs);
-        }
-    }
-    private CompileStates compileStates = new CompileStates();
-
     /** The set of currently compiled inputfiles, needed to ensure
      *  we don't accidentally overwrite an input file when -s is set.
      *  initialized by `compile'.
@@ -1395,13 +1364,17 @@
             @Override
             public void visitClassDef(JCClassDecl node) {
                 Type st = types.supertype(node.sym.type);
-                if (st.hasTag(CLASS)) {
+                boolean envForSuperTypeFound = false;
+                while (!envForSuperTypeFound && st.hasTag(CLASS)) {
                     ClassSymbol c = st.tsym.outermostClass();
                     Env<AttrContext> stEnv = enter.getEnv(c);
                     if (stEnv != null && env != stEnv) {
-                        if (dependencies.add(stEnv))
+                        if (dependencies.add(stEnv)) {
                             scan(stEnv.tree);
+                        }
+                        envForSuperTypeFound = true;
                     }
+                    st = types.supertype(st);
                 }
                 super.visitClassDef(node);
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Apr 12 12:05:04 2013 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Sat Apr 13 12:25:44 2013 +0100
@@ -59,7 +59,6 @@
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
 import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.main.JavaCompiler.CompileState;
 import com.sun.tools.javac.model.JavacElements;
 import com.sun.tools.javac.model.JavacTypes;
 import com.sun.tools.javac.parser.*;
@@ -79,6 +78,7 @@
 import com.sun.tools.javac.util.Options;
 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
 import static com.sun.tools.javac.main.Option.*;
+import static com.sun.tools.javac.comp.CompileStates.CompileState;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 
 /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8010659/CompilerCrashWhenMixingBinariesAndSourcesTest.java	Sat Apr 13 12:25:44 2013 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8010659
+ * @summary Javac Crashes while building OpenJFX
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main CompilerCrashWhenMixingBinariesAndSourcesTest
+ */
+
+public class CompilerCrashWhenMixingBinariesAndSourcesTest {
+    private static final String ASource =
+            "class A {\n" +
+            "        void test() {new B(){};}\n" +
+            "}";
+    private static final String BSource =
+            "class B extends C {}";
+    private static final String CSource =
+            "class C extends D {\n" +
+            "        String m(int i) {return null;}\n" +
+            "}";
+    private static final String DSource =
+            "class D {\n" +
+            "        Object m(int i) {return null;}\n" +
+            "}";
+
+    public static void main (String[] args) throws Exception{
+        ToolBox.JavaToolArgs javacParams = new ToolBox.JavaToolArgs()
+                .setSources(ASource, BSource, CSource, DSource);
+        ToolBox.javac(javacParams);
+
+        ToolBox.rm("A.class");
+        ToolBox.rm("A$1.class");
+        ToolBox.rm("C.class");
+        ToolBox.rm("D.class");
+
+        javacParams = new ToolBox.JavaToolArgs()
+                .setOptions("-cp", ".")
+                .setSources(ASource, CSource, DSource);
+        ToolBox.javac(javacParams);
+    }
+}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java	Fri Apr 12 12:05:04 2013 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java	Sat Apr 13 12:25:44 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -32,12 +32,12 @@
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
-import com.sun.source.util.TreePath;
 import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.main.JavaCompiler.CompileState;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.util.Context;
 
+import static com.sun.tools.javac.comp.CompileStates.CompileState;
+
 /*
  * @test
  * @summary test that type processors are run when -proc:only is passed.
--- a/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java	Fri Apr 12 12:05:04 2013 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java	Sat Apr 13 12:25:44 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -31,12 +31,12 @@
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
-import com.sun.source.util.TreePath;
 import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.main.JavaCompiler.CompileState;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.util.Context;
 
+import static com.sun.tools.javac.comp.CompileStates.CompileState;
+
 /*
  * @test
  * @summary test that package annotations are available to type processors.